一個爬蟲框架需要具備哪些功能?
不局限在語言層面
簡單來講,一個最簡化功能的爬蟲框架需要這些功能:
- 發送網路請求
- 解析HTML
- 存儲結果
但是詳細了說,其中的每一點都可以做的非常複雜,先佔個坑,晚上有時間了來填~
看這兩張圖應該就清楚了
首先web框架需要具備哪些功能。Flask,Django有模板類,Request類,Response類等,但其實最核心的是他們的路由(route)功能:即url到視圖函數的映射規則。
其次爬蟲框架需要具備哪些功能。Scrapy,pyspider有http請求庫,html解析工具,資料庫存儲等,但其實最核心的是他們的調度(scheduler)程序:即如何讓你的請求,解析,存儲協同工作。
所以一個最小的爬蟲框架只需要一套調度程序就可以了,其他的請求,解析,存儲都可以作為框架的擴展來使用,比如:For-Human/spidery。另外既然一個最小的爬蟲框架只有一套調度程序,那麼它也可以用來做非爬蟲的工作。
- 一個非爬蟲的例子
from spidery import Spider
spider = Spider([_ for _ in range(1000)])
sum = 0
@spider.http
def http(url):
return url*url
@spider.parse
def parse(response):
global sum
spider.lock.acquire()
sum += response
spider.lock.release()
return []
@spider.save
def save(item):
pass
spider.run(5) # open 5 workers
print sum
- 一個爬蟲的例子
import requests
from lxml import etree
from spidery import Spider, Item
spider = Spider(["https://movie.douban.com/tag/2016?start=" + str((i-1)*20) for i in range(1, 30)])
spider.config = open("douban.txt", "wb")
@spider.http
def http(url):
spider.log("http", "start", url)
response = requests.get(url, headers={"User-Agent": "Mozilla/5.0"})
spider.log("http", "end", url)
return response
@spider.parse
def parse(response):
Movie = Item("Movie", ["title", "rating", "vote"])
root = etree.HTML(response.text)
results = root.xpath("//div[@class="pl2"]")
for result in results:
movie = Movie()
movie["title"] = result.xpath("a/text()")[0][:-2].strip()
movie["rating"] = float(result.xpath(".//span[@class="rating_nums"]/text()")[0])
movie["vote"] = int(result.xpath(".//span[@class="pl"]/text()")[0][1:][:-4])
yield movie
@spider.save
def save(item):
spider.config.write(str(item) + "
")
spider.run(3)
但是為什麼一般的爬蟲框架都要有自己的http請求庫呢?這是因為你很難實現一套調度程序,而不考慮發送請求的方式,尤其是非同步的情形。比如,雖然For-Human/spidery實現一套多線程的調度程序,但是在使用它的時候,不建議使用非同步的請求(twisted,tornado等)。
推薦閱讀:
※爬蟲數據礦工的命運?
※標準化的互聯網採集工具的前景在哪裡?
※pyspider 和 scrapy 比較起來有什麼優缺點嗎?
※如何對使用了ssl pinning的APP(如知乎)進行抓包?
※Python 如何將 Unicode 轉換到漢字?