前言
本来这是个正经的图片爬取教程,但是考虑到正经的教程一向是不会有人看的,所以干脆满足一下各位老绅士的心理,改成了E站的爬图教学。
事先声明,本博客本质上还是个爬虫教学,所以不会提供任何ehentai访问方式和黄涩链接(代码本身也无法自动翻墙访问ehentai)。由于E站访问的问题,爬虫的效率具体也和网络稳定率有关,所以失败并不一定是代码有问题。
博主并不常访问E站(不要说了,真的全是因为你们喜欢),所以对相关的页面并不是十分了解,如果有些页面反复使用该爬虫仍无法运行,那就可能是触及到了博主的知识盲区。(不要问了,博主是不会改的,博主诸事缠身)
如何爬取网站图片
提到爬虫,就不可避免地得提到F12开发者模式(可能有的系统按键有区别,大家懂意思就行)。因为网络本身就是一个接受HTML源码并在自己的机器上编译的过程,所以绝对不存在一个你能访问但是得不到源码的网址。
得到源码后,我们就可以利用我们强大的HTML技巧,从中获取我们需要的信息。下面举例说明:
总之,我们先打开一个不太涩的E站图集。然后F12打开源码,大概就是这样: 在源码中,我们仔细调查一番后,会发现所有的图片其实都存在一个id为gdt的类中,这个大类里包含着很多子类,每个gdtm子类都是一张图片的类。类中包含着图片的大小尺寸、背景颜色……以及最重要的:图片的链接。如下
找到链接后,我们要做的就是用正则表达式把每张图片的链接提取出来,具体式子视情况而定,这里大家直接看代码就好。
随后,我们进入网址,把图片一张一张地以二进制文件格式下载下来就可以啦。
使用方法
将代码复制进python编译器中(前置包:urllib.request、urllib.parse)在main函数下按照如下格式输入: crawl(url, path, start_dex),即: crawl_picture(待爬网址,图片保存地址(请确保其存在),在该文件夹下的开始编号,默认为0(如设为1,则爬取的第一章图片编号就为1,以此类推)) 图片保存地址最后,
一定要加’\\’!,不然会保存失败。图片保存地址不一定是我这个格式(我是按windows系统来的),按照你系统的文件路径格式确定分隔符。 (可以调用多次该函数)
运行截图
第一行表示爬取该文件夹的第一页; 第二行'total success'表示与涩图文件夹第一页连接成功; 第三行'1 success'表示页面中第一张图片爬取成功,以此类推。
后面的某个网址url加success表示网址为url的图片爬取成功。
如果出现fail+url的情况,说明该url识别后没有爬取成功,可自行访问该url并检查原因。
注意点
存储地址的最后,
一——定——要——加’\\’ ,不然会报错的。由于网页存在多页的情况,为了实现跨页下载时的编号正常化,博主默认是每页40张图片(因为博主看了很多网页,好像没有特例)目前支持jpg、png、jpeg、tif、webp、gif、bmp、eps、pcx、tga、svg、psd格式图片的爬取,如果出现其他格式则无法爬取,可自行进入代码修改。(修改标注目前支持格式的下一行即可)博主做了一定的异常处理,对于爬取失败的图片会反复尝试,但是是有限度的,失败超过一定次数将会被默认不可爬取。爬取的图片会自动按照原网页中的顺序编号,从指定的dex开始不断加一。请保证保存图片的文件夹存在,这里没有做异常处理,如果失败会很尴尬。博主对E站并不熟悉,所以如果有不支持的文件夹(博主测试了一段时间,应该是没有的),可以发在评论区,请大佬改进。(博主本人是科研狗,比较繁忙,不一定有空修改)下载时成功与否与快慢与网速和与外网的连接稳定性有关系,如果失败,可以稍微试试换个网络或VPN。
代码
import urllib
.request
import urllib
.parse
import re
import time
headers
= {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
def get_picture(url
, path
, dex
):
imgList
= []
req
= urllib
.request
.Request
(url
=url
, headers
=headers
, method
='GET')
try:
response
= urllib
.request
.urlopen
(req
, timeout
=40)
text
= response
.read
().decode
('utf-8')
print("total success")
except:
return -1
picture
= re
.compile('<div class="gdtm".+?</div>', re
.DOTALL
)
all_picture_txt
=re
.findall
(picture
, text
)
picture_link
= re
.compile('(?<=<a href=").+?(?=")', re
.DOTALL
)
img_id
= re
.compile('(?<=<img id="img" src=").+?\.(jpg|png|jpeg|tif|webp|gif|bmp|eps|pcx|tga|svg|psd)', re
.DOTALL
)
cnt
= 0
for item
in all_picture_txt
:
tmp_link
= re
.search
(picture_link
, item
).group
()
req
= urllib
.request
.Request
(url
=tmp_link
, headers
=headers
, method
='GET')
flag
= 0
for times
in range(6):
try:
response
= urllib
.request
.urlopen
(req
, timeout
=15)
text
= response
.read
().decode
('utf-8')
cnt
+= 1
print(cnt
, "success")
except:
continue
else:
flag
= 1; break
if flag
:
it
= re
.search
(img_id
, text
)
if it
:
imgList
.append
(it
.group
())
else:
print('fail'+tmp_link
)
imgName
= dex
for imgPath
in imgList
:
flag
= 0
for i
in range(6):
try:
f
= open(path
+ str(imgName
)+".jpg", 'wb')
f
.write
((urllib
.request
.urlopen
(imgPath
)).read
())
print(imgPath
+' success')
f
.close
()
except:
continue
else:
flag
= 1; break
if not flag
:
print("exception",str(imgName
))
imgName
+= 1
def crawl_picture(url
, path
, start_dex
= 0):
for i
in range(10000):
print('page', i
+1, 'started!')
if i
:
out
= get_picture
(url
+'?p='+str(i
), path
, start_dex
)
else:
out
= get_picture
(url
, path
, start_dex
)
if out
== -1:
break
start_dex
+= 40
if __name__
== '__main__':
pass