Webcollector应用(二)
先吐槽一句哀家的人品,总在写好代码之后,网站默默的升级,没有一点点防备...
一、加代理
爬取一个网站的时候,爬了不到一半,IP被封了,整个内部局域网的所有电脑都不能访问网站了。
1 public class CrawlTong extends DeepCrawler{ 2 JdbcTemplate jdbcTemplate = JDBCBase.getInstance().getTemplete2(); 3 protected HttpRequesterImpl requester=(HttpRequesterImpl)this.getHttpRequester();//③ 4 public final static String name = "name"; 5 public final static String password = "password"; 6 public final static String headerKey = "Proxy-Authorization"; 7 public final static String headerValue = "Basic " + Base64.encode((name + ":" + password).getBytes()); 8 public final static int port = 50000; 9 public final static String[] proxys = { 10 "***.***.***.***", 11 "***.***.***.***", 12 "***.***.***.***"}; 13 public CrawlTong(String crawlPath ,int useProxy){ // ① 14 super(crawlPath); 15 if(useProxy == 1) { 16 requester.setHeader(ProxyCollector.headerKey, ProxyCollector.headerValue);//④ 17 //多代理随机 18 RandomProxyGenerator proxyGenerator = new RandomProxyGenerator(); // ⑤ 19 for (String proxy : proxys) { 20 proxyGenerator.addProxy(proxy,port); // ⑥ 21 } 22 requester.setProxyGenerator(proxyGenerator); // ⑧ 23 } 24 } 25 public static void main(String[] args) throws Exception{ 26 CrawlTong crawler = new CrawlTong("/tong",1); // ② 27 crawler.addSeed("https://www.tzg.cn/"); 28 crawler.start(1); 29 } 30 }
还是以应用(一)中的代码为例,可以在构造函数中添加代理:
① 在原来的基础添加了一个int型的useProxy参数,如果为1则用代理,不想用可以设置其他值
② 主函数中调用
③ 得到当前的请求requester,HttpRequesterImpl类型
④ 设置请求的Header信息,key值是"Proxy-Authorization",value值是以代理服务器的用户名和密码构成的字符串
⑤ 创建一个RandomProxyGenerator类型的对象proxyGenerator,这个类是Webcollector提供的,可以随机切换代理
⑥ 把事先定义好的代理服务器IP和端口依次放入到代理生成器中
⑧ 调用requster的setProxyGenerator方法,代理生成器传进去
为虾米没有圈7呢,因为我打不出来........
在我写这篇blog的时候,又一件积攒人品的事情发生了,哈哈哈,我这些代理服务器也被封了呢......
要考虑增加些sleep了......
二、解析json
很多页面将数据存储到单独的json文件中,所以要拿到数据,就需要对其进行解析。
解析json本身与Webcollector没什么多大关系,用java自己的方法。
1 public Links visitAndGetNextLinks(Page page) { 2 String jsonStr = page.getHtml(); 3 JSONObject json = null; 4 json = new JSONObject(jsonStr); 5 System.out.println(jsonStr); //① 6 System.out.println(json); //② 7 JSONObject msg=json.getJSONObject("msg"); //③ 8 System.out.println(msg); 9 int total = msg.getInt("total"); 10 JSONArray projectData = msg.getJSONArray("projectData"); //④ 11 System.out.println(total); 12 System.out.println(projectData); 13 for(int i = 0 ;i<projectData.length();i++){ // ⑤ 14 JSONObject object = projectData.getJSONObject(i); 15 dataModel = new DataModel(); 16 dataModel.setNumber(object.getString("thousandearnings")); 17 dataModel.setFlag(object.getInt("remain_percent")); 18 System.out.println(object.getString("thousandearnings")); 19 System.out.println(object.getInt("remain_percent")); 20 } 21 return null; 22 }
需要引入需要的包 import org.json.JSONArray; import org.json.JSONObject;....
① 和 ② 打印出来看似没有什么区别,但是呢一个是String类型,一个是Json类型,可以调用的方法不一样。
③ 通过getJSONObject方法获取JSONObject对象
JSONObject类型:json串,最外层大括号
{"A":"aaa","B":"bbb","C":[{"C1":"c1c1c1","C2":"c2c2c2"},{"CC1":"cc1cc1cc1","CC2":"cc2cc2cc2"}]}
④ 通过getJSONArray方法获取JSONArray对象
JSONArray类型: 最外层是[],里面包含json串
[{"C1":"c1c1c1","C2":"c2c2c2"},{"CC1":"cc1cc1cc1","CC2":"cc2cc2cc2"}]
⑤ 遍历JSONArray
总之:value值是什么类型的,就调用json相对应的方法获取即可