WebMagic爬虫框架
maven
<!-- webmagic -->
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
</dependency>
<!--WebMagic对布隆过滤器的支持-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0</version>
</dependency>
实例代码,包含代理设置
package com.jyft.wf.webmagic;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.downloader.HttpClientDownloader;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.proxy.Proxy;
import us.codecraft.webmagic.proxy.SimpleProxyProvider;
import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;
import java.util.List;
/**
* @Author:wf
* @Date 2021/6/12 12:18
* @Describe:抓取前程无忧的界面数据
**/
public class StatyWebMagic implements PageProcessor {
//使用正则表达式的URL匹配实例:
//目标url:http://bjjs.zjw.beijing.gov.cn/eportal/ui?pageId=320794&projectID=7007111&systemID=2&srcId=1
//编写的正则:
private static final String url ="http://bjjs\\.zjw\\.beijing\\.gov\\.cn\\/eportal\\/ui\\?pageId=\\d+&projectID=\\d+&systemID=\\d+&srcId=\\d+";
private static String startUrl="https://search.51job.com/list/000000,000000,0000,00,9,99,java,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=";
private Site site = Site.me()
//设置字符集,此处使用的字符集应该和网站使用的字符集相同,不然就会出现乱码的情况
.setCharset("gbk")
//设置超时时间为10s
.setTimeOut(10*1000)
//重试间隔时间为3S
.setRetrySleepTime(3000)
//重试次数为 3次
.setRetryTimes(3)
;
//页面解析器
@Override
public void process(Page page) {
List<Selectable> all = page.getHtml().css("div.in").nodes();
//如果为空则表示为详情页面
if(all.size()==0){
//保存数据
saveData(page);
//为空则表示为列表页面,应该解析出详情页的url,添加到任务列表中去
}else{
for (Selectable selectable : all) {
String toString = selectable.links().toString();
System.out.printf("toString-->>", toString);
//将连接添加到新的任务队列中去
page.addTargetRequest(toString);
}
//获取下一页的url
List<String> all1 = page.getHtml().css("div.p_in li.next").links().all();
//加入队列
page.addTargetRequests(all1);
}
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) {
//程序抓取的入口
Spider.create(new StatyWebMagic())
//从这个url开始抓取
.addUrl(startUrl)
//设置使用布隆过滤器去重
.setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000000)))
//设置10个线程同时抓取
.thread(10)
//使用自己的Pipeline将结果保存到数据库中
.addPipeline(new MyPipeline())
.run();
/**
* --------------设置代理服务器
*/
//创建下载器
HttpClientDownloader hcd=new HttpClientDownloader();
//设置代理服务器信息,可设置多个代理服务器,这里的代理服务器是免费的由 米扑网提供
hcd.setProxyProvider(SimpleProxyProvider.from(new Proxy("124.112.25.166",53272)));
//程序抓取的入口
Spider.create(new StatyWebMagic())
//从这个url开始抓取
.addUrl(startUrl)
//设置使用布隆过滤器去重
.setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000000)))
//设置10个线程同时抓取
.thread(10)
//使用自己的Pipeline将结果保存到数据库中
.addPipeline(new MyPipeline())
//设置包含代理的下载器
.setDownloader(hcd)
.run();
}
/**
* 保存数据
* @param page
*/
private void saveData(Page page){
Html html = page.getHtml();
//获取需要的解析数据
String title=html.css("div.cn h1","text").toString();
System.out.println("title-->>"+title);
//保存结果到内存中,然后再使用自定义的MyPipeline进行保存
page.putField("title",title);
}
}
MyPipeline类
package com.jyft.wf.webmagic;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;
/**
* @Author:wf
* @Date 2021/6/12 15:35
* @Describe:略
**/
//可以使用@Component将此类交给spring管理
public class MyPipeline implements Pipeline {
@Override
public void process(ResultItems resultItems, Task task) {
//获取刚刚储存的title
String title = resultItems.get("title");
System.out.println(title);
}
}
注:在对爬虫抓取到的文本数据,进行过滤时,比如文本A与文本B内容一致,只有标点符号不一致,这种数据若想实现过滤只是用文本A,那么可以使用,simHash进行对比,一般情况simHash提供的海平距离,大于2那么就可以视为不一样