scrapy 动态网页处理——爬取鼠绘海贼王最新漫画
简介
scrapy是基于python的爬虫框架,易于学习与使用。本篇文章主要介绍如何使用scrapy爬取鼠绘漫画网海贼王最新一集的漫画。
源码参见:https://github.com/liudaolufei/crawl-comic
网站分析
鼠绘海贼王网站网址为:http://www.ishuhui.com/comics/anime/1
漫画链接无法直接从原始网页中得到,需要点击对应的话数,链接才会显示出来,如下图所示:
获取链接后即可获得海贼王漫画的网页地址,网页如下:
原始的网页没有漫画的图片链接,需要点击图中的“连页模式”,之后网页才会显示漫画的具体内容,此时的漫画内容也是动态加载的,随着窗口不断往下,图片会一张张加载出来。
工具
scrapy: 爬虫框架
splash: 动态网页处理
环境安装
scrapy安装
已安装anaconda,python3.7版本。
创建scrapy虚拟环境并激活
1 conda create -n scrapy 2 conda activate scrapy
使用pip安装scrapy以及用于与splash交互的scrapy-splash
1 pip install scrapy scrapy-splash
在使用scrapy的ImagePipeline的时候需要第三方库PIL,安装PIL
1 pip install pillow
splash安装
splash服务是通过docker启用的,所以要先安装docker,docker安装参见:https://docs.docker.com/install/
使用docker安装splash
1 docker pull scrapinghub/splash
启用splash服务
1 docker run -p 8050:8050 scrapinghub/splash
scrapy爬虫
生成scrapy项目并生成爬虫
1 scrapy startproject crawlComics 2 cd crawlComics 3 scrapy genspider shuhui http://www.ishuhui.com/anime/1
此时在spiders文件夹下有了shuhui.py,这是爬虫的基础模板。
修改基础设置(setting.py)
使用splash的设定
1 # Splash服务器地址 2 SPLASH_URL = 'http://localhost:8050' 3 # 开启Splash的两个下载中间件并调整HttpCompressionMiddleware的次序 4 DOWNLOADER_MIDDLEWARES = { 5 'scrapy_splash.SplashCookiesMiddleware': 723, 6 'scrapy_splash.SplashMiddleware': 725, 7 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 727, 8 } 9 # 设置去重过滤器 10 DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
user-agent
1 USER_AGENT = "Mozilla/5.0 (Platform; Encryption; OS-or-CPU; Language) AppleWebKit/AppleWebKitVersion (KHTML, like Gecko)"
使用ImagePipelines保存图片的相关设定
1 # 图片存储位置 2 IMAGES_STORE = "/home/luoheng/comics/" 3 # 启用ImagesPipeline来下载图片 4 ITEM_PIPELINES = { 5 'crawlComics.pipelines.RenameImagesPipeline': 500, 6 }
添加item
item是scrapy中传输数据的基本单位,可以简单的理解为字典。
scrapy的ImagePipelines是为下载图片专门设计的,它接受一个包含键值“image_urls”和“images”的item。ImagePipelines在得到item后,会自动根据image_urls中包含的链接下载对应的图片,并放置到上文设定的IMAGE_STORE中。
故为了使用ImagePipelines,在items.py中添加一个符合条件的item:
1 class ImageItem(scrapy.Item): 2 image_urls = scrapy.Field() 3 images = scrapy.Field() 4 # store picture names 5 image_names = scrapy.Field()
前两项是为了满足ImagePipelines的要求设置的,最后一项用于设置下载图片的名字,因为ImagePipelines默认使用hash值对图片进行命名,不具可读性。
实现爬虫
爬虫主要的工作流程
1. 在http://www.ishuhui.com/anime/1页面点击最新漫画按钮,返回响应结果
2. 从响应结果中获取海贼王最新漫画的具体网址
3. 在最新漫画的网址中点击“连页模式”,并将网页拉到最下方,以使所有图片的链接加载出来,返回响应结果
4. 从响应结果中获取图片的链接,使用ImagePipelines下载
导入item与splash
1 from scrapy_splash import SplashRequest 2 from ..items import ImageItem
SplashRequest用于与splash服务进行交互,在这里主要用了splash的“execute”功能,它接受的几个参数如下:
1 SplashRequest(url, callback=self.parse, endpoint="execute", args={"lua_source": lua_script})
url是原始网址,callback是回调函数,即处理返回的response的函数,endpoint指明使用的功能,这里使用的是“execute”,即执行脚本的功能,最后一个args用于指定用于执行的脚本,这里的脚本是用lua语言写成的,在Python中以字符串形式存在。
点击最新漫画
1 click_latest_comic = """ 2 function main(splash) 3 # 打开网页 4 splash:go(splash.args.url) 5 # 等待网页加载 6 splash:wait(2) 7 # 点击最新漫画(由class ant-tag-red识别) 8 splash:runjs("document.getElementsByClassName('ant-tag-red')[0].click()") 9 # 等待网页加载 10 splash:wait(0.1) 11 # 返回网页结果 12 return splash:html() 13 end 14 """ 15 # 返回点击最新漫画后的响应结果 16 yield SplashRequest(url, callback=self.show_all, endpoint="execute", args={"lua_source": click_latest_comic})
打开具体网址,并加载所有漫画图片
show_all_pictures = """ function main(splash)# 打开网页splash:go(splash.args.url)# 等待网页加载splash:wait(2)# 点击连页模式(由class z-page识别)splash:runjs("document.getElementsByClassName('z-page')[0].click()")# 等待网页加载splash:wait(0.1)# 将网页拉到最下方,使所有图片的链接加载出来splash:runjs("window.scrollTo(0, document.body.scrollHeight)")# 等待网页加载splash:wait(0.1)# 返回响应结果return splash:html() end """def show_all(self, response):# 获取漫画具体网址target = response.css(".m-comics-num-link").xpath("@url").extract_first()# target是相对网址,它的前缀是http://www.hanhuazu.ccnew_url = "http://www.hanhuazu.cc" + target# 返回已经加载了所有图片链接的网页yield SplashRequest(new_url, endpoint="execute", args={"lua_source": show_all_pictures})
使用ImageItem保存图片链接并传送给ImagePipelines下载
1 def parse(self, response): 2 # 所有图片 3 comics = response.css("div img") 4 # src属性中保存所有图片链接,alt属性保存图片名字 5 comics_picture, comics_name = comics.xpath("@src").extract(), comics.xpath("@alt").extract() 6 # 构建ImageItem并返回给ImagePipelines 7 images = ImageItem() 8 # 保存图片链接 9 images["image_urls"] = comics_picture 10 # 保存图片链接与图片名字的映射,用于下载图片的命名 11 images["image_names"] = dict(zip(comics_picture, comics_name)) 12 # 返回后,ImagePipelines会自动下载图片 13 return images
修改ImagePipelines,覆盖默认命名
1 class RenameImagesPipeline(ImagesPipeline): 2 """to rename the images properly""" 3 4 5 def process_item(self, item, spider): 6 # add names 7 self.item_names = item["image_names"] 8 info = self.spiderinfo 9 requests = arg_to_iter(self.get_media_requests(item, info)) 10 dlist = [self._process_request(r, info) for r in requests] 11 dfd = DeferredList(dlist, consumeErrors=1) 12 return dfd.addCallback(self.item_completed, item, info) 13 14 def file_path(self, request, response=None, info=None): 15 return self.item_names[request.url]
ImagesPipeline的file_path用于计算图片的命名,但是由于图片名字保存在item的image_names属性中,而file_path并不直接接受item参数,所以需要将item["image_names"]保存到self.item_names中,如此file_path才可访问到名字。
因此将ImagesPipeline的process_item方法的代码完整复制过来,并在最前面将image_names保存到self.item_names当中,在file_path方法中只用简单调用self.item_names[request.url]即可获取图片名字。
运行爬虫
1 scrapy crawl shuhui
完成后,在comics文件夹中可以看到爬取的图片。
总结
以爬取鼠绘海贼王漫画为例,本文简单介绍了使用scrapy+splash处理动态网页的方法。
转载于:https://www.cnblogs.com/luoheng23/p/10980508.html
scrapy 动态网页处理——爬取鼠绘海贼王最新漫画相关推荐
- 网络爬虫从入门到实践(三)————动态网页的爬取
动态网页的爬取 在动态网页爬取之前,我们要了解一种异步加载更新技术--AJAX(异步的JavaScript 和XML) 他的价值在于通过在后台与服务器进行少量的数据交换就可以使用网页的某部分进行更新 ...
- scrapy爬取动态网页_scrapy_splash 爬取 js 加载网页初体验
最近打算学习 scrapy_splash 来爬取 js 加载的动态网页 selenium 实在太慢了,不在迫不得已的情况下并不推荐使用 下面,直接开始吧 目标网站 JD 某商品 环境需求 已安装 do ...
- 【python3】爬取鼠绘汉化的海贼王漫画
特别说明: 因为早些时候鼠绘的接口调整,之前的代码已经不能用了. 正好最近在学习scrapy,于是重新写了一个,项目放在github https://github.com/TurboWay/ishu ...
- 小白入门爬虫~爬取12306车次信息(静态网站和动态网站的区分)(get动态网页的爬取)
elements,console,source,network elements分析网络结构,获取想要的数据 console打印一些网站的数据,做网站的时候有时候可能会在控制台上打印一些数据 sour ...
- Windows下利用python+selenium+firefox爬取动态网页数据(爬取东方财富网指数行情数据)
由于之前用urlib和request发现只能获取静态网页数据,目前爬取动态网页有两种方法, (1)分析页面请求 (2)Selenium模拟浏览器行为(霸王硬上弓),本文讲的就是此方法 一.安装sele ...
- python动态网页图片爬取
动态网站跟静态网站的区别 在python图片爬虫中,我们爬取的是静态网站.那么静态网站跟动态网站有什么区别呢?其中对于我们写爬虫来说,最大的区别就是用requests.get()获取到的信息,动态网站 ...
- python爬取动态网页_python爬取动态网页数据,详解
原理:动态网页,即用js代码实现动态加载数据,就是可以根据用户的行为,自动访问服务器请求数据,重点就是:请求数据,那么怎么用python获取这个数据了? 浏览器请求数据方式:浏览器向服务器的api(例 ...
- python爬取京东评论分析_Python爬取京东商品评价(动态网页的爬取)
首先打开京东的任意几个商品页面,并观察URL,可以发现都是https://item.jd.com/+数字+.htm的格式,而且数字也随着商品的改变而改变,基本上可以确定这串数字是商品ID 之后我们找到 ...
- python爬取js动态网页_Python 爬取网页中JavaScript动态添加的内容(一)
当我们进行网页爬虫时,我们会利用一定的规则从返回的 HTML 数据中提取出有效的信息.但是如果网页中含有 JavaScript 代码,我们必须经过渲染处理才能获得原始数据.此时,如果我们仍采用常规方法 ...
最新文章
- js倒计时天时分秒php,JS制作分秒倒计时器
- gulp教程之gulp-htmlmin压缩html
- RHEL 8 - 记录用户会话操作
- 续:Fucking 这个网站!
- 读书笔记《高性能网站建设指南:前端工程师技能精髓》
- 大道至简——软件工程实践者的思想 读后感3
- java的编程规范_JAVA编程规范-OOP规范
- dwz怎么使用数据加载中提示_SOLIDWORKS在使用中提示内存不足怎么办?
- iOS开发-停止WebView播放视频/音频
- 10.XSD 元素替换
- 初使用tbs的x5内核所遇到的坑,初学者如何第一次跑起x5内核
- WIN10超级终端下载链接及使用教程
- 数值分析 解线性方程组的编程实现(Hilbert)
- 五 常见的计算机故障有哪些,六大常见的电脑故障原因
- 无理数究竟是什么?连续性公理的产物?——读戴德金之二
- 加菲猫台词 (请对号入座-:))
- IO操作中flush()方法作用
- GrabCut函数使用简介
- 通过ContentProvider实现获取手机联系人
- FC(nes)游戏开发资源