本帖最后由 pergrand 于 2016-7-1 21:38 编辑
爬虫的目的:
可以获得自己想要的信息,如果是电商公司可以获得竞争对手的商品价格,可以参考;
政府部门可以爬虫新闻类的网站,爬虫评论查看舆论;
还有的网站从别的网站爬虫出来在自己网站上展示。
等等
爬虫分类:
1.全网爬虫(爬取所有的网站)
2.垂直爬虫(爬取某类网站)
网络爬虫开源框架 nutch;webmagic
爬虫技术分析:
1.数据下载
模拟浏览器访问网站就是request请求response响应
可是使用httpclient
2.数据分析
将从网站下载的数据(其实就是页面html源码,在浏览器页面右击可以查看源码)
主要的工作在这个步骤,如何从一堆源码中分析解析出想要的数据
使用HTMLcleaner 和xpath 可以这样理解,HTMLcleaner从第一步下载数据(String类型),可以获得一个对象,这个对象包含整个页面的信息,
从这个对象可以通过xpath规则获得想要的html里的标签对象;遍历获得的标签对象获得的值就是我们想要的数据;(xpath类似正则表达式,这个表达式是自己根据自己想要的数据分析并调试出来的,直接根据浏览器f12获得的可能不好使)
3.数据存储
第二步已经获得数据了,可以保存了,保存方式多种多样
可以保存本地文件中,可以保存关系型数据库;如果数据大,要求数据稳定性高后期只做查询可以存储habse,如果数据量不太大,增删频繁,可以使用redis
一个简单的代码示例:爬虫一个ip代理网站;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.junit.Test;
public class TestSpider2 {
@Test
public void test2() throws Exception {
// 下载数据
HttpClientBuilder bulider = HttpClients.custom();
// 爬虫时有的网站为了反爬虫需要浏览器信息(打开网页可以f12在Headers里查看自己的信息)
bulider.setUserAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36");
CloseableHttpClient client = bulider.build();
// 将网站给get请求
HttpGet request = new HttpGet("http://www.xicidaili.com/");
CloseableHttpResponse reponse = client.execute(request);
HttpEntity entity = reponse.getEntity();
// 获得了页面的内容
String result = EntityUtils.toString(entity);
// System.out.println(result);
HtmlCleaner htmlCleaner = new HtmlCleaner();
//对页面内容进行解析,返回一个大的tagnode对象,可以认为这个tagnode对象包含整个页面的标签
TagNode rootNode = htmlCleaner.clean(result);
// 获得table里的所有tr
Object[] tbody = rootNode.evaluateXPath("//*[@id='ip_list']/tbody/tr");
for (int i = 2; i < tbody.length; i++) {
// 将每个tr标签拿出来当作TagNode对象,这个对象有每个tr里的td
TagNode trNode = (TagNode) tbody;
// 获得tr里的所有td标签
Object[] tdNode = trNode.evaluateXPath("/td");
for (int j = 1; j < tdNode.length; j++) {
// 获得td的TagNode对象
TagNode tdnNode = (TagNode) tdNode[j];
// 获得td里的值
CharSequence text = tdnNode.getText();
System.out.print(text + " ");
}
System.out.println();
}
}
}
运行部分结果:
101.201.235.141 8000 北京 高匿 HTTP 9天 1分钟前
144.52.144.154 8888 山东 高匿 HTTP 28天 1分钟前
61.183.11.243 8080 湖北武汉 高匿 HTTP 2小时 1分钟前
222.211.65.72 8080 四川成都 高匿 HTTP 13天 2分钟前
39.65.153.229 8888 山东 高匿 HTTP 16天 2分钟前
119.162.244.177 8118 山东济南 高匿 HTTP 2小时 2分钟前
60.21.132.218 63000 辽宁丹东 高匿 HTTP 256天 2分钟前
58.253.185.133 8080 广东中山 高匿 HTTP 22小时 3分钟前
222.219.100.195 8998 云南保山 高匿 HTTP 1分钟 4分钟前
36.239.55.190 8998 台湾 高匿 HTTP 1天 4分钟前
61.52.253.116 8080 河南郑州 高匿 HTTP 6天 5分钟前
121.33.226.167 3128 广东广州市从化 高匿 HTTP 147天 6分钟前
218.244.149.184 8888 北京 高匿 HTTP 17天 6分钟前
171.37.192.201 8123 广西 高匿 HTTP 1分钟 6分钟前
122.96.59.102 83 江苏南京 高匿 HTTP 999天 6分钟前
183.61.236.53 3128 广东广州 高匿 HTTP 46天 6分钟前
36.7.172.18 82 安徽 高匿 HTTP 9天 6分钟前
183.61.236.54 3128 广东广州 高匿 HTTP 49天 6分钟前
101.254.171.166 8080 高匿 HTTP 1小时 7分钟前
120.25.171.183 8080 北京 高匿 HTTP 47天 7分钟前
112.101.80.171 9797 黑龙江大庆 透明 HTTPS 415天 不到1分钟
114.36.218.39 8080 台湾 透明 HTTP 2天 不到1分钟
123.139.59.99 9999 陕西西安 透明 HTTP 17天 不到1分钟
58.67.159.50 80 广西桂林 透明 HTTPS 445天 1分钟前
27.42.237.59 9999 广东中山 透明 HTTP 6天 1分钟前
115.173.206.176 9999 上海 透明 HTTP 4天 1分钟前
124.232.148.3 3128 湖南长沙 透明 HTTP 12天 1分钟前
101.200.170.248 80 北京 透明 HTTP 4小时 1分钟前
120.83.251.200 9999 广东珠海 透明 HTTP 15小时 1分钟前
113.200.214.163 9999 陕西西安 透明 HTTP 13天 1分钟前
14.23.109.2 3128 广东 透明 HTTP 43天 1分钟前
59.78.8.190 8118 上海 透明 HTTP 20小时 1分钟前
159.226.224.180 3128 北京 透明 HTTP 210天 2分钟前
59.48.218.218 8003 山西阳泉 透明 HTTP 14天 2分钟前
119.29.232.113 3128 北京 透明 HTTP 11天 2分钟前
42.51.4.25 80 河南郑州 透明 HTTP 253天 2分钟前
5.189.243.219 8080 俄罗斯 透明 HTTP 217天 不到1分钟
202.158.20.212 80 印度尼西亚CBN网络 透明 HTTP 1天 1分钟前
185.28.193.95 8080 欧洲 透明 HTTPS 528天 1分钟前
187.95.112.0 3128 巴西 透明 HTTP 1天 1分钟前
182.53.3.119 8080 泰国 透明 HTTP 7小时 1分钟前
一个爬虫项目在实际应用中有很多其他的问题:
需要定时爬虫:可以使用一个工具类quartz(自己使用timer也可以)
一个线程的爬取速度很慢,可以开多个线程;
一台机器爬取速度也不高,使用集群(例如三个节点,每个节点开32个线程看cpu而定)
为了管理集群使用zookeeper(分布式协调服务,可以保证事务一致性,
如果有服务器挂了可以监控到;是利用临时节点的特性,关闭客户端临时节点就被删除了,
所以服务器挂后临时节点就没有了从而就可以监控到)
爬取一个网站有可能被网站封iP,假如爬取淘宝网站,一分钟几千次的频繁访问,增大了淘宝服务器的压力
如果爬取一个小网站,或者性能不高的网站例如学生管理系统,很容易把网站搞瘫痪;所以一般大型网站都做反爬虫处理
给出几种思路:
1.设置间隔时间,爬取一次睡上一秒
2.使用代理ip;上面的获得的ip就是爬取的出来的,但是网速慢,
有免费的,还有付费的,付费的网速好些,一般也不贵一个月200左右无限ip无限时间
3.上面写的使用集群 可以让不同的服务器随机抓取不同网站的数据,加上多线程在设置上时间间隔一般没问题
项目其他技术问题:
可以再项目添加日志分析,log4j+slf4j
有的数据页面源码里没有,只能根据js里查看分析做出来;
获取的有些页面乱码,在爬取时给每个网站配置编码,先查看网页的chartset信息,在存到数据库里
有的网站有登陆验证码,这个有多种方法,可以使用代理;使用图片算法获得图片信息做处理,
(对于有登录的使用post提交请求,然后再重定向页面。这一步是在第一步模拟浏览器登录时做的;
有时需要设置很多浏览器信息才能爬虫登录,因为该网站做了反爬虫处理)
纯手打,如果转载请说明。
|
|