爬虫正则获取anime图片

爬虫获取二次元图片

爬虫准备
寻找网页资源规律
爬取并保存

爬虫准备

本次我们以http://animepicsx.net/网站为例。

爬虫首先要确定的是爬虫的合法性,需要在爬取前查看网站的robots.txt,打开http://animepicsx.net/robots.txt,查看权限,并没有不允许爬取的内容,于是可以开始着手爬取了。
发现如图所示

知识准备

需要了解python及其正则表达式,html,js和http请求相关知识,这里不再赘述。

工具准备

爬取时使用python较为方便,python语言简单且库丰富,这次使用正则匹配的方式做爬虫,需要准备以下库,可以使用pip或conda安装(视你的环境而定):

  • requests库
  • re库

另外本次为方便使用anaconda的jupyter lab进行开发

寻找网页并爬取

首先我们需要查看网页结构,还是以图片为主,在按住F12后刷新网页:

网页结构
右侧出现了网页的html结构。

选中右侧窗口左上角的箭头
箭头位置
再选中其中任一张图片
图片
该元素所对应的部分就会颜色加深。

<img data-original="https://pics.animepicsx.net/images/PRQ/XUg/SxYUeL4m_r_300.jpeg" alt="" width="300" height="318" class="lazy" src="https://pics.animepicsx.net/images/PRQ/XUg/SxYUeL4m_r_300.jpeg" style="">

这样我们就清楚了图片来源,正是https://pics.animepicsx.net/images/PRQ/XUg/SxYUeL4m_r_300.jpeg

原图还是剪裁后的版本: 注意到url最后有“_300”的字样,这表明图片是经过大小规范化的版本,去掉后就是原图https://pics.animepicsx.net/images/PRQ/XUg/SxYUeL4m_r.jpeg。

同时这个网站有很多的tags,如果想要tags的话就不应在这个地方直接获取图片,而是到他的详细页面中获取,

继续观察网页结构,发现点击的a标签的href为“/37418”,这是详细页的具体地址,
即 http://animepicsx.net/37418。
网页结构
进入http://animepicsx.net/37418,同样的步骤,查看网页结构,用之前提到的箭小头点击tags的部分,一个部分亮了起来:
tags

这里的各种a标签中间的东西便是需要的tag文本

好的,思路已经清楚了,接下来就该动手实践了

爬取并保存

先写一个初始版本代码
import requests
import re

root_url = "http://animepicsx.net/"
root_html = requests.get(root_url)
#将html文本里的\n都换为空
root_html_text = root_html.text.replace("\n", "")
# print(root_html.text)

re_pattern = re.compile('<ahref="(/\d+)" class="card-image js_open_pic" target="_blank"data-img="https://.*?.jpeg" data-id="\d+"><imgdata')
detail_urls = re_pattern.findall(root_html_text);
# print(detail_urls)

发现结果只有一点数据

['/37419', '/37417', '/37416', '/37415', '/37414', '/37413', '/37411', '/37409', '/37408', '/37407', '/37406', '/37405', '/37402', '/37400', '/37397', '/37396', '/37391', '/37390', '/37379', '/37359', '/37377', '/37358', '/37376', '/37357', '/37375', '/37356']

但是数据十分有规律,于是再试试‘/5’可不可以,发现果然可以

所以之后这些网页的编号可以自行规定了,只要不超出范围即可,目前假设范围在37000张以内,之后就只需爬取具体网页即可。

先试着爬取37000的tags和高清图,

import requests
import re
detail_url = "http://animepicsx.net/" + "/37000"
detail_html = requests.get(detail_url);
# 得到具体内容后根据内容调整格式,将一些特殊字符替换
# detail_html_text = detail_html.text.replace("\n", " ")
# print(detail_html_text)

#进行正则匹配
re_pattern = re.compile('<img src="(https://pics\.animepicsx\.net/images/.*?\.jpeg)" class="z-depth-4 responsive-img">')
detail_img = re_pattern.findall(detail_html_text)
print(detail_img)

运行后果然可以获得正常的图片url。
结果
再试着获取tags:

import requests
import re
detail_url = "http://animepicsx.net/" + "/37000"
detail_html = requests.get(detail_url);
# 得到具体内容后根据内容调整格式,将一些特殊字符替换
# detail_html_text = detail_html.text.replace("\n", " ")
# print(detail_html_text)

#进行正则匹配
re_pattern = re.compile('<img src="(https://pics\.animepicsx\.net/images/.*?\.jpeg)" class="z-depth-4 responsive-img">')
detail_img = re_pattern.findall(detail_html_text)
# print(detail_img)

re_pattern = re.compile('<a href="/site/tag\?tag=(.*?)">#.*?</a>')
detail_tags = re_pattern.findall(detail_html_text)
print(detail_tags)

果然可以获得结果,与网站上的相同
结果
tags
接下来就是尝试保存图片和tags到本地,不妨就用刚刚获得的数据:

首先在本地新建一个image文件夹,名字可以在代码中改

img_url = 'https://pics.animepicsx.net/images/oH5/YS3/XRYxZJj9Vo.jpeg'
img_tags = ['blush', 'brown-hair', 'anthropomorphism', 'yellow-eyes', 'food', 'christmas']
img_data = requests.get(img_url)

img_file = open("./image/" + "37000" + ".jpeg", 'wb')
img_file.write(img_data.content)
img_file.close()

tags_file = open("./tags/" + "37000" + ".txt", 'w')
for tag in img_tags:
    tags_file.write(tag + "\n")
    
tags_file.close()

尝试后发现可以获得图片和tags文件,成功

接下来进行初始化准备:

# 添加os
import os

def main():
    # 创建文件夹,路径需要自己更改
    root_dir = "your_path"
    image_dir = root_dir + "/image"
    tags_dir = root_dir + "/tags"
    if not os.path.exists(image_dir):
        os.makedirs(image_dir)
    if not os.path.exists(tags_dir):
        os.makedirs(tags_dir)

将各种代码化为函数

import requests
import re
import os

def save_img_and_tags(img_dir, tags_dir, img_id, img_url, img_tags):
    img_data = requests.get(img_url)
    img_format = ".jpge"
    
    #可能有多种格式,需要的话再添加
    if img_url[-4: -1] == ".pn":
        img_format = ".png"
        
    img_file = open(img_dir + "/" + img_id + img_format, 'wb')
    img_file.write(img_data.content)
    img_file.close()

    tags_file = open(tags_dir + "/" + img_id + ".txt", 'w')
    for tag in img_tags:
        tags_file.write(tag + "\n")

    tags_file.close()

'''
获取该网站中特定imgId的图片和tags
@Params String imgId 
'''
def get_target_message(image_dir, tags_dir, img_id):
    detail_url = "http://animepicsx.net/" + img_id
    detail_html = requests.get(detail_url)
    detail_html_text = detail_html.text
    # print(detail_html_text)

    re_pattern = re.compile('<img\nsrc="(https://pics\.animepicsx\.net/images/.*?)" class="z-depth-4 responsive-img">')
    detail_img = re_pattern.findall(detail_html_text)
    #print(detail_img)
    img_url = detail_img[0]
    

    re_pattern = re.compile('<a\nhref="/site/tag\?tag=(.*?)">#.*?</a>')
    detail_tags = re_pattern.findall(detail_html_text)
    print("tags: ", detail_tags)
    
    save_img_and_tags(image_dir, tags_dir, img_id, img_url, detail_tags)

def main():
    # 创建文件夹
    root_dir = "your_path"
    image_dir = root_dir + "/image"
    tags_dir = root_dir + "/tags"
    # 规定网站图片张数,与网站更新到的索引有关,目前最大约37300
    image_arrange = [30000, 30010]
    
    if not os.path.exists(image_dir):
        os.makedirs(image_dir)
    if not os.path.exists(tags_dir):
        os.makedirs(tags_dir)
    
    for i in range(image_arrange[0], image_arrange[1]):
        get_target_message(image_dir, tags_dir, str(i))

另外错误处理是少不了的,在获取url后应检查是否为空,并在主函数中加入try,except处理部分,即是完整代码

import requests
import re
import os

def save_img_and_tags(img_dir, tags_dir, img_id, img_url, img_tags):
    img_data = requests.get(img_url)
    img_format = ".jpge"
    
    if img_url[-4: -1] == ".pn":
        img_format = ".png"
        

    img_file = open(img_dir + "/" + img_id + img_format, 'wb')
    img_file.write(img_data.content)
    img_file.close()

    tags_file = open(tags_dir + "/" + img_id + ".txt", 'w')
    for tag in img_tags:
        tags_file.write(tag + "\n")

    tags_file.close()

'''
获取该网站中特定imgId的图片和tags
@Params String imgId 
'''
def get_target_message(image_dir, tags_dir, img_id):
    detail_url = "http://animepicsx.net/" + img_id
    detail_html = requests.get(detail_url)
    detail_html_text = detail_html.text
    # print(detail_html_text)

    re_pattern = re.compile('<img\nsrc="(https://pics\.animepicsx\.net/images/.*?)" class="z-depth-4 responsive-img">')
    detail_img = re_pattern.findall(detail_html_text)
    #print(detail_img)
    if len(detail_img) != 1:
        raise Exception("图片获取失败")
    else:
        print("imgurl: " + detail_img[0])
        img_url = detail_img[0]
    

    re_pattern = re.compile('<a\nhref="/site/tag\?tag=(.*?)">#.*?</a>')
    detail_tags = re_pattern.findall(detail_html_text)
    print("tags: ", detail_tags)
    
    save_img_and_tags(image_dir, tags_dir, img_id, img_url, detail_tags)

def main():
    # 创建文件夹
    root_dir = "D:/program/humanPos2D"
    image_dir = root_dir + "/image"
    tags_dir = root_dir + "/tags"
    # 规定网站图片张数,与网站更新到的索引有关,目前最大约37300
    image_arrange = [30000, 30010]
    
    if not os.path.exists(image_dir):
        os.makedirs(image_dir)
    if not os.path.exists(tags_dir):
        os.makedirs(tags_dir)
    
    for i in range(image_arrange[0], image_arrange[1]):
        try:
            get_target_message(image_dir, tags_dir, str(i))
            print(str(i) + " succeed!")
        except Exception as e:
            print(str(i) + " error: ", e)

main()

完成,可以看到文件夹里都有了可以使用的图片及tags
image文件夹
tags文件夹
代码放在github了,可以去看看,Try and Enjoy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值