哎,图都没了,这个 sb csdn,简直了,算了就当自己记录了。
一、安装
安装就不说了,没什么可以说的,就 pip install pyspider 就行。
需要注意的是,写这篇文章的时候,pyspider 在 windows (至少是win7)下兼容并不好,会报错。
二、启动
我用的是 py2.7
cd 到 /usr/local/python27/lib/python2.7/site-packages/pyspider 目录下,执行 ./run.py 文件。
此时会开启一个 webui 的服务器,端口为 5000。从浏览器打开 ip:5000。
点击 create 按钮,新建一个爬虫:
此时就新建好了一个爬虫项目。
三、分析目标页面
这里我以微盘(http://vdisk.weibo.com/?cid=0&sixbread=6)练手,之所以从这里爬是因为这里是“全部”的资源列表。
在这个页面里,我们所关心的只是如图的两部分:
对于第一部分,查看其源码:
规律:http://vdisk.weibo.com/s/xxxxxxxxxxxxxx
对于第二部分,查看其源码:
规律: http://vdisk.weibo.com/?cid=0&type=&page=x
四、编码
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2017-07-20 13:41:11
# Project: weipan
from pyspider.libs.base_handler import *
import os
import json
class Handler(BaseHandler):
headers= {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, sdch',
'Accept-Language':'zh-CN,zh;q=0.8',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36'
}
crawl_config = {
'headers' : headers,
'timeout' : 100,
'itag': 'v1'
}
def on_start(self):
self.crawl('http://vdisk.weibo.com/?cid=0&sixbread=6', callback=self.index_page)
def index_page(self, response):
for each in response.doc('a[href^="http://vdisk.weibo.com/s/"]').items():
self.crawl(each.attr.href, callback=self.detail_page)
for each in response.doc('a[href^="http://vdisk.weibo.com/?cid=0&type=&page="]').items():
self.crawl(each.attr.href, callback=self.index_page)
def detail_page(self, response):
return {
"url": response.url,
"title": response.doc('title').text(),
}
def on_result(self, result):
fobj = open('/home/tanxiaolong/script/record','a')
rlt = json.dumps(result)
if rlt != 'null':
fobj.write('\n'+json.dumps(result))
首先,on_start 这里是入口,把入口地址写到 self.crawl(url, callback=self.index_page),再配置一个回调方法,这里是 index_page。意思是,首先这个爬虫会从 url 处入手爬取,并把结果返回给 index_page 方法。
第二步,在 index_page 里面,进行我们关心的两部分的分析:
for each in response.doc('a[href^="http://vdisk.weibo.com/s/"]').items():
self.crawl(each.attr.href, callback=self.detail_page)
这是第一部分,对我们的目标资源的获取。
这个是通过 response 对象的 doc 方法,查找 a 标签的 href 属性满足 http://vdisk.weibo.com/s/ 前缀的 dom, 此时的 dom 结果已经被赋给了 each 变量,通过 each.attr.href 就能获取到一个新的 url, 这个 url 将被爬取,怎么爬取?那就是第二行,继续进行 self.crawl(url,callback),将结果返回给 detail_page。
for each in response.doc('a[href^="http://vdisk.weibo.com/?cid=0&type=&page="]').items():
self.crawl(each.attr.href, callback=self.index_page)
第二部分,对页面上的下一页地址进行抓取。而这个 callback 返回的却是 index_page 为什么是 index_page 呢,因为资源页上不光有资源,还有下一页,这相当于是一个递归的爬取。
第三步,在 detail_page 里对结果进行返回
def detail_page(self, response):
return {
"url": response.url,
"title": response.doc('title').text(),
}
def on_result(self, result):
fobj = open('/home/666/script/record','a')
rlt = json.dumps(result)
if rlt != 'null':
fobj.write('\n'+json.dumps(result))
第五步,执行
①如图:
点击 run,下方的 follows 里会出现一个 “1”,点击 follows 看到里面有一个 url,这个就是入口 url,也就是说,刚才的 run 执行的是 on_start、
②如图:
点击执行按钮,会有如下结果:
点击了执行按钮后,会看到 follows 下面变成了 “34”,意思就是接下来有 34 个将要爬取的 url。
从这 34 个 url 里,我们看到了两拨 url,一个是资源的 url,一个是页码的 url。
这一步执行的就是代码里的 index_page 的方法,把页面中所有的资源和页码的 url 都爬取了下来。
③如图:
如果我执行这个,这个是一个资源的 url 吧,结果是下图:
这个 json 体就是最终的结果,你可以看到 url 和 title 两个字段。
更重要的一点是 follows 里面没有 url 了,这是因为这个资源已经是最终的地址了,里面再没有符合要求的 url 了。那么这个爬取就会结束返回结果并且跳出来,执行下一个。
这一步执行的是 detail_page 方法,即返回了我们所要爬取的结果内容——url 和 title。
那如果你点击了页码的执行,如下图:
你将看到如下结果:
又有 34 个待爬 url,而且这 34 个中也是分两拨,一个是资源的,一个是页码的。这一步相当于又执行了 index_page 这个方法,递归了。
所以从上面的执行来看 pyspider 应该是深度优先(DFS)的爬虫系统。
而且,这个 pyspider 很有 tensorflow 流式的感觉,这点很赞。
第六步、开爬
回到 ip:5000,切换爬虫的状态未 running ,然后点右边的 run,就不用管了。你可以 tail -f 你的落地文件,看看结果:
这就是 pyspider 的初探。还蛮好用。