有各种语言版本号的开源爬虫。c++, Java, php,在github上搜一下,以"spider c++"为keyword,有245个开源爬虫,以"spider java"为keyword。有48个。
那python呢?156个。
爬虫技术在业界已经非常成熟了。有非常多开源框架,在它们的帮助下写爬虫能够非常快,几个小时就能写一个不错的东东用。
爬虫技术也会非常复杂。假设要做分布式抓取和全文检索,一般使用Nutch。
最有名的Python爬虫框架是Scrapy,这个名字也蛮有意思的,预计是Spider。Crawler,python各取部分字符组合起来的。它的官方主页在http://scrapy.org/。
1. 安装Scrapy
安装Scrapy非常easy,linux系统的话,一条语句就能够了。"sudo pip install Scrapy"。
通常python在Linux各发行版上都是默认安装的。pip是python的包管理工具,运行install命令后。它会从网上下载最新版本号的Scrapy安装。安装完成。在命令行输入命令"scrapy version"。会打印scrapy的版本号。表明成功安装。
2. 生成项目文件夹
假设要抓取大众点评网,须要先创建项目。选择一个空文件夹,比方在我的电脑上是/tmp/scrapy-test。在命令行输入"scrapy startproject crawdp",startproject是scrapy的一个命令。执行后,在/tmp/scrapy-test文件夹会出现一个新文件夹crawdp。它包括scrawdp项目所须要的一切东东,如源码和配置文件。
执行"tree crawdp",能够看到整个文件夹结构。
那么,"startproject""创建项目"这个高大上字眼背后的真相是什么呢?事实上不复杂,就是创建一个项目名的文件夹和它的几个子文件夹,然后复制几个指定的文件到这些文件夹,再把这些文件中的几个特定字符串替换成项目名。这块的代码在scrapy源码的scrapy/command/commands文件夹下的startproject.py文件中。而在"tree crawdp"看到的文件。它们的原型在scrapy/templates/project/module文件夹下,如settings.py.tmpl文件,把它里面的字符串"$project_name"用"crawdp"替换,再把文件名称改成settings.py,就是crawdp的settings.py文件。
像settings.py.tmpl这种文件。又称为模板文件。把模板里的变量用字符串替换掉。叫渲染(render)。在web server的开发中也相同使用这种技术,前端工程师设计html文件,里面包括形如"$project_name"之类的变量,保存成模板文件,而服务器在执行的时候,用执行时产生的字符串替换掉模板里的变量,再把替换后的内容发给浏览器,就是我们看到的网页,所以叫动态页面。
3. 第一个spider
開始写第一个spider,这是一个很easy的spider,仅仅有13行代码。
在/tmp/scrapy-test/crawdp/crawdp/spiders文件夹下,创建文件cityid_spider.py。内容例如以下:
-----------------------------------------
from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
class CityidSpider(BaseSpider):
name = "cityid_spider"
start_urls = ["http://www.dianping.com/shanghai/food"]
def parse(self, response):
hxs = HtmlXPathSelector(response)
xs = hxs.select('//ul[@class="nc_list"]/li/a/@href')
x = xs[0]
cityid = x.extract().split('/')[3]
print "
cityid = %s
" % cityid
-----------------------------------------
返回到/tmp/scrapy-test/crawdp/文件夹,在这个文件夹下运行"scrapy crawl cityid_spider",能够看到打印出来的结果是"cityid = 1",在默认配置下,顺带会打印非常多log信息,所以我在这句加了几个换行符。让它显示得清楚一点。
注意,这里有几个关键点:
a. cityid_spider.py这个文件,必须放在/tmp/scrapy-test/crawdp/crawdp/spiders文件夹下,放在别的地方,scrapy找不到。
b. 源码里。name = "cityid_spider"这句必须有。这里指定了spider的名字,scrapy靠名字识别不同的spider。
c. 必须在/tmp/scrapy-test/crawdp/下运行"scrapy crawl cityid_spider",在别的文件夹下不行。
其它的,能够把class CityidSpider类名换成别的,没关系,也能够cityid_spider.py文件名称换成别的名字,也没关系。不影响效果。
这个spider是一切spider的基本型,更复杂的spider都是在它的基础上逐渐加入很多其它功能做出来的。
4. 这个spider是干什么的
在大众点评网,每一个城市都有一个数字代号,比方上海是1,北京是2。深圳是7。它家的总部在上海。所以上海是1号。假设想抓很多其它城市的餐厅,就须要知道城市代号。
上海的城市代号,能够从http://www.dianping.com/shanghai/food抓取。在浏览器打开http://www.dianping.com/shanghai/food,在左側的“商区”以下,有“陆家嘴”,在它上面点击右键。选择“审查元素”,假设你用的是chrome,浏览器会开一个窗体,用高亮色定位到陆家嘴相应的html元素。这个元素包括一个超级链接。叫"/search/category/1/10/r801" 。那么上海的cityid就是超级链接里的category后面"1",而这个链接。是嵌套在一个固定的层次式的html元素里。也就是形如代码里形如"//ul[@class="nc_list"]/li/a/@href"的结构。这样的写法叫xpath。
执行"scrapy crawl cityid_spider"的时候,spider開始执行,它先检查spider源码里的“start_urls = ["http://www.dianping.com/shanghai/food"]”,依据这个url,从大众点评网上抓取html文件内容。存在response里,然后调用parse函数,从response里用xpath解析出全部符合"//ul[@class="nc_list"]/li/a/@href"的html元素,取第一个。得到一个类似“/search/category/1/10/r801”的字符串,然后将它以'/'为间隔做切割,取第3个。就是"1",就是cityid,这就是parse函数的前四条语句做的事情。
这块写的略有一点不人性化。术语比較多。那么,想做抓取的话,至少要懂一点html,css,web server,xpath。稍微有点基础即可。这些东西在这里就不展开了,找本入门书看看就能够了。