分类目录归档:爬虫

使用scrapy满足各种爬虫需求

玩爬虫也有很长一段时间了,一直没做一个记录,经常在同一个坑中跌倒,做个记录吧。

1.ImportError: Error loading object ‘scrapy.core.downloader.handlers.s3.S3DownloadHandler’: No module named win32api

安装pywin32 : http://sourceforge.net/projects/pywin32/

2.新版本(1.0+)如果spider再继承于scrapy.spider 不会执行rules,被这坑了好久,果断看了官方文档,发现变动还挺大的,几个包都变了

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
spider也得继承于CrawlSpider,如果不重载parse,会自动根据rules抓取

3.初始化爬虫用start_url不能满足需求,需要配置Request
重载函数

def start_requests(self):yield request

4.需要在middleware或parse的时候复用request并更改url

request.replace(url = new_url)

5.需要得到配置文件或更改爬虫配置
重载函数,cls 为当前类,若是自己写的扩展需要在settings.py中声明

@classmethod
def from_crawler(cls, crawler, *args, **kwargs):return cls(*args, **kwargs)

6.得到当前spider配置文件

from scrapy.utils import project
self.settings = project.get_project_settings()

7.获取crawler状态信息

crawler.stats.get_stats()

8.随机变换代理及useragent
定义自己的middleware,设置request.meta的保留字段proxy
useragent 为设置reques.headers
返回None,继续处理此request

def process_request(self,request,spider):
    request.meta['proxy'] ="http://127.0.0.1:8888"
    request.headers.setdefault('User-Agent', ua)

9.部署scrapyd,需要创建配置文件 /etc/scrapyd/scrapyd.conf

[scrapyd]
eggs_dir    = {your dir}/eggs
logs_dir    = {your dir}/logs
items_dir   = {your dir}/items
jobs_to_keep = 100
dbs_dir     ={your dir}/dbs
max_proc    = 0
max_proc_per_cpu = 4
finished_to_keep = 100
poll_interval = 10
http_port   = 6800
debug       = on
runner      = scrapyd.runner
application = scrapyd.app.application
launcher    = scrapyd.launcher.Launcher

[services]
schedule.json     = scrapyd.webservice.Schedule
cancel.json       = scrapyd.webservice.Cancel
addversion.json   = scrapyd.webservice.AddVersion
listprojects.json = scrapyd.webservice.ListProjects
listversions.json = scrapyd.webservice.ListVersions
listspiders.json  = scrapyd.webservice.ListSpiders
delproject.json   = scrapyd.webservice.DeleteProject
delversion.json   = scrapyd.webservice.DeleteVersion
listjobs.json     = scrapyd.webservice.ListJobs
daemonstatus.json = scrapyd.webservice.DaemonStatus

10.使用scrapyd运行爬虫,出错
scrapyd CRITICAL: Unhandled error in Deferred:

'scrapy.telnet.TelnetConsole': None,
'scrapy.extensions.feedexport.FeedExporter': None,

使用chrome调试xpath

相信玩过爬虫的都知道一些库,如lxml(python),可以使用xpath方便地对HTML进行提取,但当真正用的时候,问题就来了,想找到一个元素往往要调试好几遍,而且得先code,下面提供了几个工具及如何用chrome进行xpath test

1.XPath Helper

https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl

1. Open a new tab and navigate to your favorite webpage.
2. Hit Ctrl-Shift-X to open the XPath Helper console.
3. Hold down Shift as you mouse over elements on the page. The query box will continuously update to show the full XPath query for the element below the mouse pointer. The results box to its right will show the evaluated results for the query.
4. If desired, edit the XPath query directly in the console. The results box will immediately reflect any changes.
5. Hit Ctrl-Shift-X again to close the console.

2.Xpath Finder – xpath查找助手

https://chrome.google.com/webstore/detail/xpath-finder/ijaobnmmgonppmablhldddpfmgpklbfh/related

在chrome开发者工具里增加一个面板,帮助你快速查找匹配XPATH表达式的元素。

1. 匹配的节点会用红色边框突出显示。
2. 在结果列表里可以直接inspect对应节点。
3. 记录XPATH查找历史,方便查看历史。

3.chrome console

F12->$x(“//title”)

[<title>Online Tools for Software Developers (Free)</title>]

百度搜索结果链接转实际链接

转自:http://enenba.com/?post=237

好像从9-1开始,百度搜索结果网址的链接又开始变成这样了,”link?url=…….”,是老长老长的。自己官方SEO手册说要简短URL,什么不超过128个字符。都是浮云,看这下面一个搜索结果
我的“enenba”的搜索结果(2012-9-3)第一个网址就是

'http://www.baidu.com/link?url=ab848a4ebf3b154d5a26b46af889a39ac4eed0923116bcf0318bb786a19e417e714ea3b262d4ef8546b80f8d6cffdd1552a3595fad2084b2b04cf1a10c36485f8a3f73ced8eee0c4f9284ad8daefcb15794a404724dc8678af321201bce1cf69814e1920005bc796e241dcc9c45664d62bb227b184af812305040ecc1bab45fff26deb422fc77779a618a28d269f82c2a58db607e54d3abcff2e6a43376ae429f1088b77dbde4b1348c11ea7c7e88ec03ce7484d89fe244390e628bc04b824e78dc62f0d12df46f100fcd70a1cc2783360150eaee4b9b6928700cb776e5b84abc69565c04e97800c615c84e640fb7b971cdd88ca6478f8d07a28058dd50ab7879c3340ad84d7c6e9fb779710a060cc6d26cbdb0ab7e7f8b70ffd77e025470569f0be3580991c83d6db4b78c2f7e75713c73c8683feebeded81088e8706b23c64747f20084e726f0de41906254a0f0983430a990861e8ddd9fd1d832b872aebac5573358cc3c0659257bfcf54763ec1c5ecff3b3fbd1d4c'

目前还是找不到什么规律的,不过想要得到跳转后的网址也不难。
我又挖了以前的文章了:

 

 

<?php
/*
	getrealurl 获取301、302重定向后的URL地址  by enenba.com
	@param str $url 查询
	$return str  定向后的url的真实url
 */
function getrealurl($url){
	$header = get_headers($url,1);
	if (strpos($header[0],'301') || strpos($header[0],'302')) {
		if(is_array($header['Location'])) {
			return $header['Location'][count($header['Location'])-1];
		}else{
			return $header['Location'];
		}
	}else {
		return $url;
	}
}


//恶心的一长串字符
$url = 'http://www.baidu.com/link?url=ab848a4ebf3b154d5a26b46af889a39ac4eed0923116bcf0318bb786a19e417e714ea3b262d4ef8546b80f8d6cffdd1552a3595fad2084b2b04cf1a10c36485f8a3f73ced8eee0c4f9284ad8daefcb15794a404724dc8678af321201bce1cf69814e1920005bc796e241dcc9c45664d62bb227b184af812305040ecc1bab45fff26deb422fc77779a618a28d269f82c2a58db607e54d3abcff2e6a43376ae429f1088b77dbde4b1348c11ea7c7e88ec03ce7484d89fe244390e628bc04b824e78dc62f0d12df46f100fcd70a1cc2783360150eaee4b9b6928700cb776e5b84abc69565c04e97800c615c84e640fb7b971cdd88ca6478f8d07a28058dd50ab7879c3340ad84d7c6e9fb779710a060cc6d26cbdb0ab7e7f8b70ffd77e025470569f0be3580991c83d6db4b78c2f7e75713c73c8683feebeded81088e8706b23c64747f20084e726f0de41906254a0f0983430a990861e8ddd9fd1d832b872aebac5573358cc3c0659257bfcf54763ec1c5ecff3b3fbd1d4c';

$url = getrealurl($url);
echo 'enenba真实的url为:'.$url;


?>

看到百度再怎么301跳转我都可以找得到。

 

end

从nutch索引里面,读取文章内容

nutch作为一个完整的搜索引擎,是广大搜索爱好者学习的一个好项目。然而,因为nutch自己封装了一套严谨的IO操作类,要查看原始网页的内容,也不容易。在毕业设计的过程中,经过一般的摸索,可以由索引得到每个网页的原始内容。因此,后继的文本分类的研究也得以展开。代码如下:

import org.apache.lucene.search.IndexSearcher;
import java.io.*;
import org.apache.lucene.document.Document;
import org.apache.nutch.searcher.FetchedSegments;
import org.apache.nutch.fs.LocalFileSystem;
import java.util.ArrayList;
import java.util.Enumeration;
import org.apache.lucene.document.Field;
import org.apache.nutch.searcher.HitDetails;
public class ExtractText {
 public ExtractText() {
 }
 public static void main(String[] args) throws IOException {

   String path = args[0];//nutch crawl完的主目录 如crawl-20060622203455
   File nutchFileRoot = new File(path);
   File index = new File(nutchFileRoot,”index”);
   File segmentsDir = new  File(nutchFileRoot,”segments”);
   File outPut = new File(nutchFileRoot,”plaitext”);//存放内容的目录
   if(!outPut.isDirectory()){
     outPut.mkdir();
   }

   FetchedSegments segments = new FetchedSegments(new LocalFileSystem(), segmentsDir.toString());

   try {
     IndexSearcher searcher = new IndexSearcher(index.getAbsolutePath());
     
     for(int i = 0;i<searcher.maxDoc();i++){
       Document doc = searcher.doc(i);//依次遍历索引库中的每条记录
        
        String docNo = doc.get(“docNo”);
        String seg  = doc.get(“segment”);

        ArrayList fields = new ArrayList();
        ArrayList values = new ArrayList();

        Enumeration e = doc.fields();
        while (e.hasMoreElements()) {
          Field field = (Field)e.nextElement();
          fields.add(field.name());
          values.add(field.stringValue());
        }
       HitDetails detail = new HitDetails((String[])fields.toArray(new String[fields.size()]),
                              (String[])values.toArray(new String[values.size()]));
       
       String aa = segments.getParseText(detail).toString();//得到内容
       
       File temp =  new File(outPut,seg+”_”+docNo);//输出文件的名字,可以随便起,保证不重复就可以
       DataOutputStream outs = new DataOutputStream(new FileOutputStream(temp));
       outs.write(aa.getBytes());
       outs.close();

     }
   } catch (IOException ex) {
     ex.printStackTrace();
   }

 }
}

转自:http://hi.baidu.com/sunky/blog/item/40702ff5c42a9b25bd310949.html

Nutch中使用自定义中文分词器

原文:http://xtfncel.iteye.com/blog/756763

Nutch中使用自定义中文分词器

Nutch对中文查询时默认采用的分词器为NutchAnalyzer,对中文默认采用单字切分.这种效果不是很理想,我们可以自定义切词器,以实现对中文支持.

通常可以采用的两种方式添加对中文的支持:

1.采用插件的方式,不修改系统代码的基础上,编写中文分词插件实现对中文分词的支持。

2.直接修改nutch的系统代码,对默认的分词器代码进行修改使其使用自定义中文分词程序.

继续阅读

Nutch中文分词总结

1 中文分词介绍

中文分词是在做检索类系统时需要重点考虑的一个因素。Nutch的本土化过程也需要更改对中文分词的支持。目前,Nutch中文分词方式大致有两种方式:

一是修改源代码。这种方式是直接对Nutch分词处理类进行修改,调用已写好的一些分词组件进行分词。

二是编写分词插件。这种方式是按照Nutch定义的插件编写规则重新编写或者添加中文分词插件。

以上两种方式都是可取的。目前,由于开源社区的活跃,已经有很多种分词组件的出现,无论是修改源代码的方式还是编写分词插件的方式,都是依赖于这些分词组件的。下面列出了主要的一些分词组件:

继续阅读

开源网络爬虫介绍及其比较

原文链接:http://cq-cser.cn/2010/06/开源网络爬虫介绍及其比较/

开源网络爬虫介绍及其比较

Planet – Chinahttp://secinn.appspot.com/planet/feed?site=cn

Nutch

开发语言:Java

http://lucene.apache.org/nutch/

简介:

Apache的子项目之一,属于Lucene项目下的子项目。

Nutch是一个基于Lucene,类似Google的完整网络搜索引擎解决方案,基于Hadoop的分布式处理模型保证了系统的性能,类似Eclipse的插件机制保证了系统的可客户化,而且很容易集成到自己的应用之中。

Larbin

开发语言:C++

http://larbin.sourceforge.net/index-eng.html

简介

larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人 Sébastien Ailleret独立开发。larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供广泛的数据来源。

Larbin只是一个爬虫,也就是说larbin只抓取网页,至于如何parse的事情则由用户自己完成。另外,如何存储到数据库以及建立索引的事情 larbin也不提供。

latbin最初的设计也是依据设计简单但是高度可配置性的原则,因此我们可以看到,一个简单的larbin的爬虫可以每天获取500万的网页,非常高效。

Heritrix

开发语言:Java

http://crawler.archive.org/

简介

与Nutch比较

和 Nutch。二者均为Java开源框架,Heritrix 是 SourceForge上的开源产品,Nutch为Apache的一个子项目,它们都称作网络爬虫/蜘蛛( Web Crawler),它们实现的原理基本一致:深度遍历网站的资源,将这些资源抓取到本地,使用的方法都是分析网站每一个有效的URI,并提交Http请求,从而获得相应结果,生成本地文件及相应的日志信息等。

Heritrix 是个 “archival crawler” — 用来获取完整的、精确的、站点内容的深度复制。包括获取图像以及其他非文本内容。抓取并存储相关的内容。对内容来者不拒,不对页面进行内容上的修改。重新爬行对相同的URL不针对先前的进行替换。爬虫通过Web用户界面启动、监控、调整,允许弹性的定义要获取的URL。

二者的差异:

Nutch 只获取并保存可索引的内容。Heritrix则是照单全收。力求保存页面原貌

Nutch 可以修剪内容,或者对内容格式进行转换。

Nutch 保存内容为数据库优化格式便于以后索引;刷新替换旧的内容。而Heritrix 是添加(追加)新的内容。

Nutch 从命令行运行、控制。Heritrix 有 Web 控制管理界面。

Nutch 的定制能力不够强,不过现在已经有了一定改进。Heritrix 可控制的参数更多。

Heritrix提供的功能没有nutch多,有点整站下载的味道。既没有索引又没有解析,甚至对于重复爬取URL都处理不是很好。

Heritrix的功能强大 但是配置起来却有点麻烦。

其他网络爬虫介绍:

 

WebLech 
WebLech是一个功能强大的Web站点下载与镜像工具。它支持按功能需求来下载web站点并能够尽可能模仿标准Web浏览器的行为。WebLech有一个功能控制台并采用多线程操作。
http://weblech.sourceforge.net/
Arale 
Arale主要为个人使用而设计,而没有像其它爬虫一样是关注于页面索引。Arale能够下载整个web站点或来自web站点的某些资源。Arale还能够把动态页面映射成静态页面。
http://web.tiscali.it/_flat/arale.jsp.html

J-Spider 
J-Spider:是一个完全可配置和定制的Web Spider引擎.你可以利用它来检查网站的错误(内在的服务器错误等),网站内外部链接检查,分析网站的结构(可创建一个网站地图),下载整个Web站点,你还可以写一个JSpider插件来扩展你所需要的功能。
http://j-spider.sourceforge.net/

spindle 
spindle 是一个构建在Lucene工具包之上的Web索引/搜索工具.它包括一个用于创建索引的HTTP spider和一个用于搜索这些索引的搜索类。spindle项目提供了一组JSP标签库使得那些基于JSP的站点不需要开发任何Java类就能够增加搜索功能。
http://www.bitmechanic.com/projects/spindle/

Arachnid 
Arachnid: 是一个基于Java的web spider框架.它包含一个简单的HTML剖析器能够分析包含HTML内容的输入流.通过实现Arachnid的子类就能够开发一个简单的Web spiders并能够在Web站上的每个页面被解析之后增加几行代码调用。 Arachnid的下载包中包含两个spider应用程序例子用于演示如何使用该框架。
http://arachnid.sourceforge.net/

LARM 
LARM能够为Jakarta Lucene搜索引擎框架的用户提供一个纯Java的搜索解决方案。它包含能够为文件,数据库表格建立索引的方法和为Web站点建索引的爬虫
http://larm.sourceforge.net/

JoBo 
JoBo 是一个用于下载整个Web站点的简单工具。它本质是一个Web Spider。与其它下载工具相比较它的主要优势是能够自动填充form(如:自动登录)和使用cookies来处理session。JoBo还有灵活的下载规则(如:通过网页的URL,大小,MIME类型等)来限制下载。
http://www.matuschek.net/software/jobo/index.html

snoics-reptile 
snoics -reptile是用纯Java开发的,用来进行网站镜像抓取的工具,可以使用配制文件中提供的URL入口,把这个网站所有的能用浏览器通过GET的方式获取到的资源全部抓取到本地,包括网页和各种类型的文件,如:图片、flash、mp3、zip、rar、exe等文件。可以将整个网站完整地下传至硬盘内,并能保持原有的网站结构精确不变。只需要把抓取下来的网站放到web服务器(如:Apache)中,就可以实现完整的网站镜像。
http://www.blogjava.net/snoics

Web-Harvest 
Web-Harvest是一个Java开源Web数据抽取工具。它能够收集指定的Web页面并从这些页面中提取有用的数据。Web-Harvest主要是运用了像XSLT,XQuery,正则表达式等这些技术来实现对text/xml的操作。
http://web-harvest.sourceforge.net

spiderpy
spiderpy是一个基于Python编码的一个开源web爬虫工具,允许用户收集文件和搜索网站,并有一个可配置的界面。
http://pyspider.sourceforge.net/

The Spider Web Network Xoops Mod Team 
pider Web Network Xoops Mod是一个Xoops下的模块,完全由PHP语言实现。
http://www.tswn.com/

HiSpider is a fast and high performance spider with high speed

严格说只能是一个spider系统的框架, 没有细化需求, 目前只是能提取URL, URL排重, 异步DNS解析, 队列化任务, 支持N机分布式下载, 支持网站定向下载(需要配置hispiderd.ini whitelist).

特征和用法:

  • 基于unix/linux系统的开发
  • 异步DNS解析
  • URL排重
  • 支持HTTP 压缩编码传输 gzip/deflate
  • 字符集判断自动转换成UTF-8编码
  • 文档压缩存储
  • 支持多下载节点分…

 

Methanol 是一个模块化的可定制的网页爬虫软件,主要的优点是速度快。