爬虫系统-多线程

package com.open111.crawler;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
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.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
*
* 爬虫起始类
* @author user
*
*/
public class StartCrawler {

private static Logger logger=Logger.getLogger(StartCrawler.class);

public static String[] excludeUrl=new String[]{ ".pom", ".xml", ".md5", ".sha1", ".asc", ".gz", ".zip", "../"}; // 要过滤的url后缀

public static Queue<String> waitForCrawlerUrls=new LinkedList<String>(); // 等待爬取的url

private static int total=0;

private static boolean exeFlag=true;

/**
* 解析网页内容
* @param webPageContent
*/
public static void parseWebPage(String webPageContent,String realPath){
if("".equals(webPageContent)){
return;
}
Document doc=Jsoup.parse(webPageContent);
Elements links=doc.select("a"); // 获取所有超链接元素
for(int i=0;i<links.size();i++){
Element link=links.get(i);
String url=link.attr("href");
boolean f=true;
for(int j=0;j<excludeUrl.length;j++){
if(url.endsWith(excludeUrl[j])){
f=false;
break;
}
}
if(f){ // 是我们需要的url
if(url.endsWith(".jar")){ // 目标地址
total++;
logger.info("发现第"+total+"个目标:"+(realPath+url));
}else{ // 要继续解析的Url
logger.info("爬虫url队列新增url:"+(realPath+url));
addUrl(realPath+url,"解析网页");
}
}
}
}

/**
* 添加url到爬虫队列,假如队列中存在 就不添加
* @param string
*/
private static void addUrl(String url,String info) {
if(url==null || "".equals(url)){
return;
}
if(!waitForCrawlerUrls.contains(url)){
waitForCrawlerUrls.add(url);
logger.info("["+info+"]"+url+"添加到爬虫队列");
}
}

/**
* 解析网页请求
* @param url 请求的url
*/
public static void parseUrl(){
ExecutorService executorService=Executors.newFixedThreadPool(10);
while(exeFlag){
if(waitForCrawlerUrls.size()>0){
executorService.execute(new Runnable() {

public void run() {
// TODO Auto-generated method stub
String url=waitForCrawlerUrls.poll(); // 摘取第一个元素
if(url==null || "".equals(url)){
return;
}
logger.info("执行解析url:"+url);
RequestConfig requestConfig=RequestConfig.custom().setSocketTimeout(100000) // 设置读取超时时间
.setConnectTimeout(5000) // 设置连接超时时间
.build();
CloseableHttpClient httpClient=HttpClients.createDefault(); // 创建httpclient实例
HttpGet httpGet=new HttpGet(url); // 创建httpget实例
httpGet.setConfig(requestConfig);
CloseableHttpResponse response=null;
try {
response=httpClient.execute(httpGet);
} catch (ClientProtocolException e) {
logger.error("ClientProtocolException", e);
addUrl(url,"由于异常");
} catch (IOException e) {
logger.error("IOException", e);
addUrl(url,"由于异常");
}
if(response!=null){
HttpEntity entity=response.getEntity(); // 获取返回实体
if("text/html".equals(entity.getContentType().getValue())){
String webPageContent=null;
try {
webPageContent = EntityUtils.toString(entity, "utf-8");
parseWebPage(webPageContent,url);
} catch (ParseException e) {
logger.error("ParseException", e);
addUrl(url,"由于异常");
} catch (IOException e) {
logger.error("IOException", e);
addUrl(url,"由于异常");
}
}
try {
response.close();
} catch (IOException e) {
logger.error("IOException", e);
addUrl(url,"由于异常");
}
}else{
logger.info("连接超时");
addUrl(url,"由于异常");
}
}
});
}else{
if(((ThreadPoolExecutor)executorService).getActiveCount()==0){ // 活动线程是0
executorService.shutdown(); // 结束所有线程
exeFlag=false;
logger.info("爬虫任务已经成功");
}
}

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
logger.error("线程休眠报错",e);
}
}

}

private static void init(){
logger.info("读取爬虫配置文件");
FileInputStream fis=null;
InputStreamReader isr=null;
BufferedReader br=null;
try {
String str=null;
fis=new FileInputStream("c:\\crawler.txt");
isr=new InputStreamReader(fis);
br=new BufferedReader(isr);
while((str=br.readLine())!=null){
addUrl(str, "初始化");
}
} catch (FileNotFoundException e) {
logger.error("FileNotFoundException", e);
} catch (IOException e) {
logger.error("IOException", e);
}finally{
try {
br.close();
isr.close();
fis.close();
} catch (IOException e) {
logger.error("IOException", e);
}
}
logger.info("完成读取爬虫配置文件");
parseUrl();
}

public static void main(String[] args) {
logger.info("开始执行爬虫任务");
init();
}
}

时间: 2024-10-14 08:47:44

爬虫系统-多线程的相关文章

用python3.x与mysql数据库构建简单的爬虫系统(转)

这是在博客园的第一篇文章,由于本人还是一个编程菜鸟,也写不出那些高大上的牛逼文章,这篇文章就是对自己这段时间学习python的一个总结吧. 众所周知python是一门对初学编程的人相当友好的编程语言,就像本屌丝一样,一学就对它产生好感了!当然,想要精通它还有很多东西需要学习.那废话不多说了,下面我就来说一下如何用python3.x与mysql数据库构建一个简单的爬虫系统(其实就是把从网页上爬下来的内容存储到mysql数据库中). 首先就是搭建环境了,这里就简介绍一下我的环境吧.本机的操作系统是w

NodeJS爬虫系统初探

NodeJS爬虫系统 NodeJS爬虫系统 0. 概论 爬虫是一种自动获取网页内容的程序.是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上是针对爬虫而做出的优化. robots.txt是一个文本文件,robots.txt是一个协议,不是一个命令.robots.txt是爬虫要查看的第一个文件.robots.txt文件告诉爬虫在服务器上什么文件是可以被查看的,搜索机器人就会按照该文件中的内容来确定访问的范围. 一般网站的robots.txt查找方法: 例如www.qq.com http://ww

微信公众号 文章的爬虫系统

差不多俩个星期了吧,一直在调试关于微信公众号的文章爬虫系统,终于一切都好了,但是在这期间碰到了很多问题,今天就来回顾一下,总结一下,希望有用到的小伙伴可以学习学习. 1.做了俩次爬虫了,第一次怕的凤凰网,那个没有限制,随便爬,所以也就对自动化执行代码模块放松了警惕,觉得挺简单的,但是其实不是这样的,我被这个问题困扰了好几天,差不多4天的一个样子,因为搜狗做的限制,同一个ip获取的次数多了,首先是出现验证码,其次是就是访问限制了,直接就是不能访问,利用 request得到的就是访问次数过于频繁,这

编写一个猥琐的反爬虫系统是种怎样的体验

我们所处的互联网, 是一个爬虫的世界.任何一个小公司,小团队,甚至一个应届毕业生,都有可能编写爬虫,偷偷的获取数据. 当你看到“爬虫”两个字的时候, 就应该有点血脉贲张的感觉了. 爬虫就如同病毒一样无孔不入.有的爬虫肆无忌惮地访问资源,导致服务器性能下降甚至崩溃:有的爬虫如同间谍一样秘密入侵,伪装成用户获取本不应该让它获取到的数据:有的爬虫冒充搜索引擎,堂而皇之的威胁你交出数据,可能还明目张胆的写各种教程嘲笑你们,是可忍孰不可忍?! 然而,千万要忍耐,稍稍做点什么,可以在名义上让他们胜利,实际上

高效爬虫系统的设计

作者:邹祁峰 邮箱:[email protected] 博客:http://blog.csdn.net/qifengzou 日期:2015.02.06 转载请注明来自"祁峰"的CSDN博客 1 引言 在互联网上可找到很多关于爬虫系统的设计和实现的相关文档,但仔细阅读后可发现绝大多数的设计方案的可用性.可靠性.高效性.扩展性等方面均存在很多问题. 针对以上问题的存在,本设计方案将以可用性.可靠性.高效性.可扩展性为基本准则重新设计爬虫系统. 2 处理时序 图1 爬虫系统时序图

python爬虫实战,多线程爬取京东jd html页面:无需登录的网站的爬虫实战

[前言] # 本脚本用来爬取jd的页面:http://list.jd.com/list.html?cat=737,794,870到 # ......http://list.jd.com/list.html?cat=737,794,870&page=11&JL=6_0_0的所有html的内容和图片. # 本脚本仅用于技术交流,请勿用于其他用途 # by River # qq : 179621252 # Date : 2014-12-02 19:00:00 [需求说明] 以京东为示例,爬取页面

定时爬虫系统(以爬取[百度7日关注]为例)

1.web.xml加载servlet 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.su

爬虫之多线程案例

多线程糗事百科案例 案例要求参考上一个糗事百科单进程案例 Queue(队列对象) Queue是python中的标准库,可以直接import Queue引用;队列是线程间最常用的交换数据的形式 python下多线程的思考 对于资源,加锁是个重要的环节.因为python原生的list,dict等,都是not thread safe的.而Queue,是线程安全的,因此在满足使用条件下,建议使用队列 初始化: class Queue.Queue(maxsize) FIFO 先进先出 包中的常用方法: Q

单线程爬虫VS多线程爬虫的效率对比

单线程爬虫: import re import requests import time url_EB = 'http://www.amazon.com/gp/search/other/ref=sr_sa_p_4?me=A22XNR713HGDVG&rh=n%3A9063592011%2Ck%3Aprojector&bbn=9063592011&keywords=projector&pickerToList=brandtextbin&ie=UTF8&qid=