WebMagic 实现爬虫入门教程
本示例实现某电影网站最新片源名称列表及详情页下载地址的抓取。
webmagic是一个开源的java垂直爬虫框架,目标是简化爬虫的开发流程,让开发者专注于逻辑功能的开发。
webmagic 特点:
完全模块化的设计,强大的可扩展性。
核心简单但是涵盖爬虫的全部流程,灵活而强大,也是学习爬虫入门的好材料。
提供丰富的抽取页面api。
无配置,但是可通过pojo+注解形式实现一个爬虫。
支持多线程。
支持分布式。
支持爬取js动态渲染的页面。
无框架依赖,可以灵活的嵌入到项目中去。
示例
本示例实现:https://www.dytt8.net/html/gndy/dyzz/list_23_1.html 电影网站最新片源名称及详情页影片下载链接内容的抓取。
配置maven依赖
pom.xml配置,这里因为日志文件和spring boot冲突了,所以移除webmagic的日志依赖 log4j12
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.1.9.release</version> <relativepath/> <!-- lookup parent from repository --> </parent> <groupid>com.easy</groupid> <artifactid>webmagic</artifactid> <version>0.0.1</version> <name>webmagic</name> <description>demo project for spring boot</description> <properties> <java.version>1.8</java.version> <encoding>utf-8</encoding> <project.build.sourceencoding>utf-8</project.build.sourceencoding> <project.reporting.outputencoding>utf-8</project.reporting.outputencoding> </properties> <dependencies> <dependency> <groupid>us.codecraft</groupid> <artifactid>webmagic-core</artifactid> <version>0.7.3</version> <exclusions> <exclusion> <groupid>org.slf4j</groupid> <artifactid>slf4j-log4j12</artifactid> </exclusion> </exclusions> </dependency> <dependency> <groupid>us.codecraft</groupid> <artifactid>webmagic-extension</artifactid> <version>0.7.3</version> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
创建列表及详情页解析类
pageprocessor负责解析页面,抽取有用信息,以及发现新的链接。webmagic使用jsoup作为html解析工具,并基于其开发了解析xpath的工具xsoup。
listpageprocesser.java 实现影片名称列表获取
package com.easy.webmagic.controller; import us.codecraft.webmagic.page; import us.codecraft.webmagic.site; import us.codecraft.webmagic.processor.pageprocessor; public class listpageprocesser implements pageprocessor { private site site = site.me().setdomain("127.0.0.1"); @override public void process(page page) { page.putfield("title", page.gethtml().xpath("//a[@class='ulink']").all().tostring()); } @override public site getsite() { return site; } }
detailpageprocesser.java 实现详情页影片下载地址获取
package com.easy.webmagic.controller; import us.codecraft.webmagic.page; import us.codecraft.webmagic.site; import us.codecraft.webmagic.processor.pageprocessor; public class detailpageprocesser implements pageprocessor { private site site = site.me().setdomain("127.0.0.1"); @override public void process(page page) { page.putfield("download", page.gethtml().xpath("//*[@id=\"zoom\"]/span/table/tbody/tr/td/a").tostring()); } @override public site getsite() { return site; } }
使用pipeline处理抓取结果
pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。webmagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。
pipeline定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的pipeline。对于一类需求一般只需编写一个pipeline。
这里不做任何处理,直接把抓包到的结果在控制台输出
mypipeline.java
package com.easy.webmagic.controller; import lombok.extern.slf4j.slf4j; import us.codecraft.webmagic.resultitems; import us.codecraft.webmagic.task; import us.codecraft.webmagic.pipeline.pipeline; import java.util.map; @slf4j public class mypipeline implements pipeline { @override public void process(resultitems resultitems, task task) { log.info("get page: " + resultitems.getrequest().geturl()); for (map.entry<string, object> entry : resultitems.getall().entryset()) { log.info(entry.getkey() + ":\t" + entry.getvalue()); } } }
启动抓包入口
main.java
package com.easy.webmagic.controller; import us.codecraft.webmagic.spider; public class main { public static void main(string[] args) { //获取影片标题和页面链接 spider.create(new listpageprocesser()).addurl("https://www.dytt8.net/html/gndy/dyzz/list_23_1.html") .addpipeline(new mypipeline()).thread(1).run(); //获取指定详情页面的影片下载地址 spider.create(new detailpageprocesser()).addurl("https://www.dytt8.net/html/gndy/dyzz/20191204/59453.html") .addpipeline(new mypipeline()).thread(1).run(); } }
运行示例
启动运行main.java,观察控制台
影片第一页标题列表
14:06:28.704 [pool-1-thread-1] info com.easy.webmagic.controller.mypipeline - get page: https://www.dytt8.net/html/gndy/dyzz/list_23_1.html 14:06:28.704 [pool-1-thread-1] info com.easy.webmagic.controller.mypipeline - title: [<a href="/html/gndy/dyzz/20191204/59453.html" class="ulink">2019年剧情《中国机长》hd国语中英双字</a>, <a href="/html/gndy/dyzz/20191201/59437.html" class="ulink">2019年动画喜剧《雪人奇缘》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191201/59435.html" class="ulink">2019年喜剧《伯纳黛特你去了哪》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191129/59431.html" class="ulink">2019年高分剧情《爱尔兰人/爱尔兰杀手》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191129/59429.html" class="ulink">2019年剧情《唐顿庄园电影版》bd中英双字[修正字幕]</a>, <a href="/html/gndy/dyzz/20191129/59428.html" class="ulink">2018年悬疑动作《雪暴》bd国语中字</a>, <a href="/html/gndy/dyzz/20191128/59427.html" class="ulink">2019年剧情惊悚《官方机密》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191127/59425.html" class="ulink">2019年高分剧情《少年的你》hd国语中字</a>, <a href="/html/gndy/dyzz/20191126/59424.html" class="ulink">2019年剧情冒险《攀登者》hd国语中英双字</a>, <a href="/html/gndy/dyzz/20191126/59423.html" class="ulink">2019年剧情《金翅雀》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191125/59422.html" class="ulink">2019年高分获奖《好莱坞往事》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191125/59421.html" class="ulink">2018年动画冒险《猫与桃花源》bd国粤双语中字</a>, <a href="/html/gndy/dyzz/20191124/59418.html" class="ulink">2019年恐怖《准备好了没/弑婚游戏》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191124/59417.html" class="ulink">2019年剧情悬疑《双魂》bd国粤双语中字</a>, <a href="/html/gndy/dyzz/20191122/59409.html" class="ulink">2019年科幻动作《双子杀手》hd中英双字幕</a>, <a href="/html/gndy/dyzz/20191122/59408.html" class="ulink">2019年奇幻《天堂山/天堂山�f》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191121/59407.html" class="ulink">2019年恐怖《小丑回魂2》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191117/59403.html" class="ulink">2019年高分动画《克劳斯:圣诞节的秘密》bd国英西三语双字</a>, <a href="/html/gndy/dyzz/20191116/59400.html" class="ulink">2019年动作《天使陷落》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191115/59399.html" class="ulink">2019年悬疑惊悚《犯罪现场》hd国粤双语中字</a>, <a href="/html/gndy/dyzz/20191115/59398.html" class="ulink">2019年高分剧情《别告诉她》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191114/59393.html" class="ulink">2019年动作《原始恐惧》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191114/59392.html" class="ulink">2019年剧情《婚礼之后》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191113/59387.html" class="ulink">2019年动作战争《危机:龙潭之战》bd中英双字幕</a>, <a href="/html/gndy/dyzz/20191113/59386.html" class="ulink">2019年犯罪动作《沉默的证人》bd国粤双语中字</a>]
详情页影片下载地址
14:06:34.365 [pool-2-thread-1] info com.easy.webmagic.controller.mypipeline - get page: https://www.dytt8.net/html/gndy/dyzz/20191204/59453.html 14:06:34.365 [pool-2-thread-1] info com.easy.webmagic.controller.mypipeline - download: <a href="ftp://ygdy8:ygdy8@yg45.dydytt.net:4233/阳光电影www.ygdy8.com.中国机长.hd.1080p.国语中英双字.mkv">ftp://ygdy8:ygdy8@yg45.dydytt.net:4233/阳光电影www.ygdy8.com.中国机长.hd.1080p.国语中英双字.mkv</a>
表示成功抓取到数据,然后做你想做的事情了。
爬虫进阶
使用selectable抽取元素
selectable相关的抽取元素链式api是webmagic的一个核心功能。使用selectable接口,你可以直接完成页面元素的链式抽取,也无需去关心抽取的细节。
爬虫的配置、启动和终止
spider是爬虫启动的入口。在启动爬虫之前,我们需要使用一个pageprocessor创建一个spider对象,然后使用run()进行启动。同时spider的其他组件(downloader、scheduler、pipeline)都可以通过set方法来进行设置。
jsoup和xsoup
webmagic的抽取主要用到了jsoup和我自己开发的工具xsoup。
爬虫的监控
利用这个功能,你可以查看爬虫的执行情况——已经下载了多少页面、还有多少页面、启动了多少线程等信息。该功能通过jmx实现,你可以使用jconsole等jmx工具查看本地或者远程的爬虫信息。
配置代理
proxyprovider有一个默认实现:simpleproxyprovider。它是一个基于简单round-robin的、没有失败检查的proxyprovider。可以配置任意个候选代理,每次会按顺序挑选一个代理使用。它适合用在自己搭建的比较稳定的代理的场景。
处理非http get请求
采用在request对象上添加method和requestbody来实现。例如:
request request = new request("http://xxx/path"); request.setmethod(httpconstant.method.post); request.setrequestbody(httprequestbody.json("{'id':1}","utf-8"));
使用注解编写爬虫
webmagic支持使用独有的注解风格编写一个爬虫,引入webmagic-extension包即可使用此功能。
在注解模式下,使用一个简单对象加上注解,可以用极少的代码量就完成一个爬虫的编写。对于简单的爬虫,这样写既简单又容易理解,并且管理起来也很方便。
资料
上一篇: Python连载56-发送带有附件、正文为HTML的邮件
下一篇: 服务发现(consul)搭建