如何用python爬取e-hentai的图片

    科技2024-11-14  13

    前言

    本来这是个正经的图片爬取教程,但是考虑到正经的教程一向是不会有人看的,所以干脆满足一下各位老绅士的心理,改成了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) #目前支持jpg、png、jpeg、tif、webp、gif、bmp、eps、pcx、tga、svg、psd 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__': #crawl_picture('https://e-hentai.org/g/1742413/26779d61ba/', 'D:\\本子\\', 0) pass
    Processed: 0.028, SQL: 8