GuozhongCrawler看准网爬虫动态切换IP漫爬虫

有些关于URL去重的方面代码没有提供,须要自己去实现。主要这里提供思路

项目地址:http://git.oschina.net/woshidaniu/GuozhongCrawler/tree/master/example/changeProxyIp/

首先爬虫入口类:

public class PervadeSpider {

public static void main(String[] args) {

CrawTaskBuilder builder = CrawlManager.getInstance()

.prepareCrawlTask("看准网漫爬虫", DefaultPageDownloader.class)

.useThread(200)// 使用多个线程下载

.useDynamicEntrance(DynamicEntranceImpl.class)

.useProxyIpPool(KanzhunProxyIpPool.class, 800, 1000 * 60 * 20, 30)

.useQueueSimpleBlockingRequest()//採用广度优先策略,当然redis队列也是fifo。

假设想做分布式爬虫的话能够设置redis队列

.usePageEncoding(PageEncoding.UTF8);

CrawlTask spider = builder.build();

CrawlManager.getInstance().start(spider);

}

public static final class DynamicEntranceImpl extends DynamicEntrance{

@Override

public List<StartContext> loadStartContext() {

StartContext context = new StartContext();

context.injectSeed(context.createPageRequest("http://www.kanzhun.com/companyl/search/?

ka=banner-com", ExtractUrlPageProcessor.class));//公司

context.injectSeed(context.createPageRequest("http://www.kanzhun.com/salaryl/search/?stype=&ka=banner-salary", ExtractUrlPageProcessor.class));//工资

context.injectSeed(context.createPageRequest("http://www.kanzhun.com/jobl/p/?

ka=banner-recruit", ExtractUrlPageProcessor.class));//招聘

context.injectSeed(context.createPageRequest("http://www.kanzhun.com/interviewl/search/?stype=&ka=banner-interview", ExtractUrlPageProcessor.class));//面试

context.injectSeed(context.createPageRequest("http://www.kanzhun.com/topic/100.html?ka=com-topic-1", ExtractUrlPageProcessor.class));//公司之最

return Arrays.asList(context);

}

}

}

动态代理IP提供类:

public class KanzhunProxyIpPool extends ProxyIpPool {

public static final String IP_RESOURCE = "地址忽略";//地址请求的个数必须设置为initProxyIp(int size)中size的个数

public KanzhunProxyIpPool(int initSize, long pastTime, int max_use_count) {

super(initSize, pastTime, max_use_count);

}

private Pattern extractIp = Pattern.compile("([\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}):(\\d+)");

@Override

protected List<ProxyIp> initProxyIp(int size) throws Exception {

List<ProxyIp>   ip = new ArrayList<ProxyIp>();

URL url = null;

BufferedReader br = null;

StringBuffer buf = new StringBuffer();

try {

url = new URL(IP_RESOURCE);

InputStream in = url.openStream();

br = new BufferedReader(new InputStreamReader(in,"utf-8"));

String temp = null;

while((temp = br.readLine())!=null){

buf.append(temp).append("\n");

}

ProxyIp proxy = null;

Matcher matcher = extractIp.matcher(buf);

while(matcher.find()){

proxy = new ProxyIp(matcher.group(1), Integer.parseInt(matcher.group(2)));

ip.add(proxy);

}

} catch (Exception e) {

e.printStackTrace();

System.out.println(buf);

}finally{

if(br != null){

try {

br.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

return ip;

}

}

漫爬页面处理类:

public class ExtractUrlPageProcessor implements PageProcessor {

private String domain = "http://www.kanzhun.com";

private List<URLFilter> urlFilters = new ArrayList<URLFilter>();

private List<Pattern> urlRegulars = null;

public ExtractUrlPageProcessor(){

System.out.println("载入漫爬抽取URL正则");

urlRegulars = ConfigReader.getExtractRegular();

System.out.println("载入漫爬规则完成");

addURLFilter(new URLFilter() {

@Override

public boolean filter(String url) {

return !url.contains("javascript");//去除jquery标签

}

});

addURLFilter(new URLFilter() {

@Override

public boolean filter(String url) {

return url.contains("http://www.kanzhun.com");//保证域名内URL

}

});

addURLFilter(new URLFilter() {

@Override

public boolean filter(String url) {

for (Pattern pattern : urlRegulars) {

boolean result = pattern.matcher(url).find();

if(result)

return true;

}

return false;//保证url符合urlRegulars里随意一个正则

}

});

}

/**

* kanzhunId抽取正则

*/

final static Pattern[] idExtracts = new Pattern[]{

Pattern.compile("gso(\\d+)[^\\d]+"),//简单介绍抽取公司id

Pattern.compile("gsr(\\d+)[^\\d]+"),//点评抽取公司id

Pattern.compile("gsm(\\d+)[^\\d]+"),//面试抽取公司id

Pattern.compile("gsx(\\d+)[^\\d]+"),//工资抽取公司id

Pattern.compile("g(\\d+)[^\\d]+"),//招聘抽取公司id

Pattern.compile("gsp(\\d+)[^\\d]+"),//照片抽取公司id

Pattern.compile("gsl(\\d+)[^\\d]+")//员工抽取公司id

};

@Override

public PageScript getJavaScript() {

// TODO Auto-generated method stub

return null;

}

private Pattern normalContain = Pattern.compile("看准网");

@Override

public Pattern getNormalContain() {

return normalContain;

}

@Override

public void process(OkPage page,StartContext context,List<BasicRequest> queue,List<Proccessable> objectContainer) throws Exception {

// TODO Auto-generated method stub

/**

* 每一个页面抽取的符合urlRegulars规则的url

*/

Set<String> extractUrls = new HashSet<String>();

/**

* 每一个页面全部的kanzhunId

* 这里解释下比方阿里巴巴的首页是http://www.kanzhun.com/gso9012.html?ka=com1-title

* 那个阿里巴巴的kanzhunId就是9012

* 我们能够依据这个推导出阿里巴巴的

* 点评页:http://www.kanzhun.com/gsr9012.html?ka=com-blocker1-review

* 面试页:http://www.kanzhun.com/gsm9012.html?ka=com-blocker1-interview

* 工资页:http://www.kanzhun.com/gsx9012.html?ka=com-blocker1-salary

* 招聘页:http://www.kanzhun.com/job/g9012.html?ka=com-blocker1-job

* 照片页:http://www.kanzhun.com/gsp9012.html?ka=com-blocker1-photo

* 员工页:http://www.kanzhun.com/gsl9012.html?ka=com-blocker1-employee

*

*/

Set<String> kanzhunIds = new HashSet<String>();

Document doc = Jsoup.parse(page.getContent());

Elements allLinks = doc.select("a");

String href = null;

for (Element link : allLinks) {

href = link.attr("href");

if(href.startsWith("/")){

href = domain+href;

}

if(pass(href)){

extractUrls.add(href);

}

//抽取页面全部包括的kanzhunID

for (Pattern pattern : idExtracts) {

Matcher matcher = pattern.matcher(href);

if(matcher.find()){

kanzhunIds.add(matcher.group(1));

}

}

}

//step1

System.out.println(page.getRequest().getUrl()+"抽取了URL"+extractUrls.size()+"个:");

//对url去重(这个须要你们自己实现这里用伪代码表示)

System.out.println("去出反复url...");

//step2

System.out.println(page.getRequest().getUrl()+"抽取了kanzhunId"+kanzhunIds.size()+"个:");

//对抓过的kanzhunId进行去重(这个须要你们自己实现这里用伪代码表示)

System.out.println("kanzhunId进行去重...");

//将抽取的URL增加到队列

for (String extractUrl:extractUrls) {

PageRequest pageRequest = context.createPageRequest(extractUrl, ExtractUrlPageProcessor.class);

queue.add(pageRequest);//加到队列

}

//将抽取的kanzhunId封装成每一个企业的主页URL。

抓取企业信息

for (String kanzhunId:kanzhunIds) {

PageRequest pageRequest = context.createPageRequest("http://www.kanzhun.com/gso"+kanzhunId+".html?

ka=com1-title", CompanyPageProcessor.class);

queue.add(pageRequest);//加到队列

}

}

@Override

public void processErrorPage(Page arg0, StartContext arg1) throws Exception {

// TODO Auto-generated method stub

}

/**

* 对每一个URL进行filter

* @param url

* @return

*/

private boolean pass(String url){

for (URLFilter filter : urlFilters) {

if(!filter.filter(url)){

return false;

}

}

return true;

}

public void addURLFilter(URLFilter urlFilter){

urlFilters.add(urlFilter);

}

}

最后URL抽取规则贴上。

<ExtractRegular>

<!-- 行业URL 或者 公司标签  或者 城市-->

<Regular>/pl[act][a-z0-9]+\.html</Regular>

<!-- 行业URL 或者 城市-->

<Regular>/xs[ac][a-z0-9]+\.html</Regular>

<!-- 招聘分类URL-->

<Regular>/jobli_.+</Regular>

<!-- 面试分类URL-->

<Regular>/ms[ac].+</Regular>

<!-- 公司之最-->

<Regular>/topic/[a-z0-9]+</Regular>

<!-- 热门职位-->

<Regular>/salary/(\d+)/</Regular>

<Regular>/interview/(\d+)/</Regular>

</ExtractRegular>

搞定。

时间: 2024-10-18 00:11:51

GuozhongCrawler看准网爬虫动态切换IP漫爬虫的相关文章

(转)内网网站发布到外网-nat123动态公网IP动态域名解析

环境描述: 路由器分配的是动态公网IP,且有路由器登录管理权限,网站服务器部署在路由器内部网络.如何将内网网站发布到外网大众访问? 解决方案: 内网使用nat123动态域名解析,将域名实时固定解析到路由公网IP,然后在路由器上做网站端口映射.外网访问网站时,使用动态解析域名. 实现过程: 1,明确网站内网访问地址端口,确保网站服务正常,在内网可以正常访问连接.如我内网网站访问地址是192.168.1.22:80.如果本地公网IP的80端口被屏蔽,可以更换其他网站端口,或使用nat123的80映射

node.js 爬虫动态代理ip

参考文章: https://andyliwr.github.io/2017/12/05/nodejs_spider_ip/ https://segmentfault.com/q/1010000008196143 代码: import request from 'request'; import userAgents from './common/userAgent'; //这里只做测试,所以用变量存,而实际应用中,应该使用数据缓存 const expiryTime = 10 * 60 * 100

看准网免登录查看隐藏评论/面经

Target www.kanzhun.com Method 地址栏.html后添加 ?kan=com-blocker1-interview Test 原始地址 After 原文地址:https://www.cnblogs.com/gglin/p/10063306.html

java实现动态切换上网IP (ADSL拨号上网)

动态切换IP的实现主是也由Windows的rasdial命令提供的,其实不是java的功劳,java只是调用一下bat脚本而已: rasdial命令: 拨号 Java代码   语法: rasdial  连接名称 username password 实例: rasdial 我的宽带 hzhz1234567890 dfdfdfdfdf 断网 Java代码   语法:rasdial  连接名称 /disconnect 实例: rasdial 宽带  /disconnect java程序调用rasdia

亿牛云爬虫代理设置自主切换IP的方案

1.自主切换IP?该模式适合一些需要登陆.Cookie缓存处理等爬虫需要精确控制IP切换时机的业务. 爬虫程序可以通过设置HTTP头Proxy-Tunnel: 随机数, 当随机数相同时,访问目标网站的代理IP相同. 例如 需要登录,获取数据两个请求在一个IP下,只需对这组请求设置相同Proxy-Tunnel,例如:Proxy-Tunnel: 12345, 该组请求在代理有效期内使用相同的代理IP. 注意 同一时间不同请求组可以设置不同Proxy-Tunnel: 随机数,并发完成数据爬取. 使用相

简单爬虫,突破IP访问限制和复杂验证码,小总结

简单爬虫,突破复杂验证码和IP访问限制 文章地址:http://www.cnblogs.com/likeli/p/4730709.html   好吧,看题目就知道我是要写一个爬虫,这个爬虫的目标网站有一些反爬取意识,所以就有了本文了. 我先说说场景吧: 由于工作需要,平时有一大堆数据需要在网上查询,并归档存库.某次,这种任务也给我安排了一份.观察了一网站,我的第一反应就是用爬虫取抓取.这种机械的工作何必人工呢? 由于这家网站有反爬虫的意识,做了些工作,给我的爬虫去爬取数据造成了某些麻烦. 先列举

爬虫 解决网页ip限制的问题的八种方法

方法1. 之前由于公司项目需要,采集过google地图数据,还有一些大型网站数据. 经验如下: 1.IP必须需要,像@alswl 说的非常正确,ADSL.如果有条件,其实可以跟机房多申请外网IP. 2.在有外网IP的机器上,部署代理服务器. 3.你的程序,使用轮训替换代理服务器来访问想要采集的网站. 好处: 1.程序逻辑变化小,只需要代理功能. 2.根据对方网站屏蔽规则不同,你只需要添加更多的代理就行了. 3.就算具体IP被屏蔽了,你可以直接把代理服务器下线就OK,程序逻辑不需要变化. 方法2.

动态切换数据库(EF框架)

         文章简略:本文测试项目为Silverlight+EF+RIA Service动态切换数据库的问题 通常,Ado.net EntityFramework的数据库连接字符串ConnectionString是存在实体框架所在的类库项目中的配置文件中(.config)的,类似这样: <connectionStrings> <add name="{EFName}Entities" connectionString="metadata=res://*/

django 板块动态切换

需求:在同一页面的不同板块上可以实现动态切换,使用一个view实现,具体如下图所示,点击phy显示物理机列表,点击vm显示虚机列表,phy.vm对应的url均是动态生成:               实现思路: 1.新建两个表,servers表用于存放服务器种类,pvserver物理机虚机具体服务器信息.物理机和虚机不要分别存放于两个表中,这样的话在view中无法直接通过服务器类型得出相应的服务器列表 #存放服务器类型 class servers(models.Model): serverid