《python3網路爬蟲開發實戰》--pyspider

weixin_30765475發表於2018-10-18

1. 與scrapy的比較:

  • pyspider提供 了 WebUI,爬蟲的編寫、除錯都是在 WebUI 中進行的 。 而 Scrapy原生是不具備這個功能的,它採用的是程式碼和命令列操作,但可以通過對接 Portia實現視覺化配置。
  • pyspider除錯非常方便 , WebUI操作便捷直觀。 Scrapy則是使用 parse命令進行除錯, ;民:方便程度不及 p)叩ider。
  • pyspider支援 PhantomJS來進行 JavaScript誼染頁面的採集 。 Scrapy可以對接 Scrapy-Splash元件,這需要額外配置 。
  • pyspider中內建了 pyquery作為選擇器。 Scrapy對接了 XPath、 css選擇器和正則匹配。

  • pyspider 的可擴充套件程度不足,可配製化程度不高 。 Scrapy 可以 通過對接 Middleware、 Pipeline、Extension等元件實現非常強大 的功能, 模組之間的稠合程度低,可擴充套件程度極高 。

2. pyspider的架構:

    pyspider的架構主要分為 Scheduler (排程器)、 Fetcher (抓取器)、 Processer (處理器) 三個部分,整個爬取過程受到 Monitor (監控器)的監控,抓取的結果被 Result Worker (結果處理器)處理。

Scheduler 發起任務排程, Fetcher 負責抓取網頁內容, Processer 負責解析網頁內容,然後將新生成的 Request發給 Scheduler進行排程,將生成的提取結果輸出儲存。

  • 每個 pyspider 的專案對應一個 Python j閱本,該指令碼中定義了一個 Handler 類,它有一個on_start()方法。 爬取首先呼叫 on_start()方法生成最初的抓取任務,然後傳送給 Scheduler進行排程 。
  • Scheduler將抓取任務分發給 Fetcher進行抓取, Fetcher執行並得到響應,隨後將響應傳送給Processer。
  • Processer 處理響應並提取 H-',新的 URL 生成新的抓取任務,然後通過訊息佇列的方式通知Schduler 當前抓取任務執行情況,並將新生成的抓取任務傳送給 Scheduler。 如果生成了新的提取結果,則將其傳送到結果佇列等待 ResultWorker處理。
  • Scheduler 接收到新的抓取任務,然後查詢資料庫,判斷其如果是新的抓取任務或者是需要重試的任務就繼續進行排程,然後將其傳送回 Fetcher進行抓取。
  • 不斷重複以上工作,直到所有的任務都執行完畢,抓取結束 。
  • 抓取結束後,程式會回撥 on_finished()方法,這裡可以定義後處理過程。

3.使用

pyspider all

http:localhost:5000

當爬取網頁無法載入圖片時,可能是圖片是由JS渲染的

1 def index_page(self, response):
2         for each in response.doc('li > .tit > a').items():
3             self.crawl(each.attr.href,
4                        callback=self.detail_page,
5                        fetch_type='js')#啟用PhantomJS渲染
6             next = response.doc('.next').attr.href
7             self.crawl(next,callback=self.index_page)
 1 from pyspider.libs.base_handler import *
 2 
 3 
 4 class Handler(BaseHandler):
 5     crawl_config = {
 6     }
 7 
 8     @every(minutes=24 * 60)
 9     def on_start(self):
10         self.crawl('http://travel.qunar.com/travelbook/list.htm', callback=self.index_page)
11 
12     @config(age=10 * 24 * 60 * 60)
13     def index_page(self, response):
14         for each in response.doc('li > .tit > a').items():
15             self.crawl(each.attr.href,
16                        callback=self.detail_page,
17                        fetch_type='js')
18             next = response.doc('.next').attr.href
19             self.crawl(next,callback=self.index_page)
20 
21     @config(priority=2)
22     def detail_page(self, response):
23         return {
24             "url": response.url,
25             #"title": response.doc('title').text(),
26             "title": response.doc('#booktitle').text(),
27             "date": response.doc('.when .data').text(),
28             "day": response.doc('.howlong .data').text(),
29             "who": response.doc('.who .data').text(),
30             "text": response.doc('#b_panel_schedule').text(),
31             "image": response.doc('.cover_img').attr.src
32         }

 

rate/burst代表當前的爬取速率, rate代表 l 秒發IH多少個請求, burst相當於流量控制中的令牌桶演算法的令牌數, rate和 burst設定的越大,爬取速率越快,當然連率需要考慮本機效能和爬取過快被封的問題。 process中的 5m、 lh、 ld指的是最近 5分、l 小時 、 l 天內的請求’情況, all 代表所有的請求情況 。 請求由不同顏色表示,藍色的代表等待被執行的請求 ,綠色的代表成功的請求,黃色的代表請求失敗後等待重試的請求,紅色的代表失敗次數過 多rfi被忽略的請求,這樣可以直觀知道爬取的進度和請求情況.

pyspider [OPTIONS) COMMAND [ARGS)

 1 Options:
 2     -c, --config FILENAME 指定配置檔名稱
 3     --logging-config TEXT 日誌配置檔名稱 ,預設 :pyspider/pyspider/logging.conf
 4     --debug  開啟除錯模式
 5     --queue-maxsize INTEGER 佇列的最大長反
 6     --taskdb TEXT taskdb 的資料庫連線字串,預設: sqlite
 7     --projectdb TEXT  projectdb 的資料庫連線字串,預設: sqlite
 8     --resultdb TEXT resultdb 的資料庫連線字串,預設: sqlite
 9     --message-queue TEXT  訊息隊連線字串,預設· multiprocessing.Queue
10     --phantomjs-proxy TEXT  PhantomJS 使用的代理, ip:port 的形式
11     --data-path TEXT   資料庫存放的路徑
12     --version  pyspider 的版本
13     --help   顯示幫助資訊
14   

crawl用法

• url
url是爬取時的 URL,可以定義為單個 URL字串,也可以定義成 URL列表

• callback
callback是回撥函式,指定了該 URL對應的響應內容用哪個方法來解析,

• age
age 是任務的有效時間 。 如果某個任務在有效時間內且已經被執行,則它不會重複執行

• priority

priority 是爬取任務的優先順序,其值預設是 0,priority 的數值越大,對應的請求會越優先被排程,

• exetime

exetime引數可以設定定時任務,其值是時間戳,預設是 0,即代表立即執行

• retries

retries 可以定義重試次數,其值預設是 3。

• itag

itag 引數設定判定網頁是存發生變化的節點值,在爬取時會判定次當前節點是否和上次爬取到的節點相同 。 如果節點相同,則證明頁面沒有更新,就不會重複爬取,

• auto recrawl
當開啟 時,爬取任務在過期後會重新執行,迴圈時間即定義的 age 時間長度

• method

method是 HTTP請求方式,它預設是 GET。 如果想發起 POST請求,可以將 method設定為 POST。

• params

我們可以方便地使用 params 來定義 GET請求引數

• data

data是 POST表單資料。 當請求方式為 POST時,我們可以通過此引數傳遞表單資料

• files
files 是上傳的檔案,需要指定檔名

• user_agent

user_agent 是爬取使用的 User-Agent。

• headers

headers是爬取時使用的 Headers,即 Request Headers

cookies

cookies 是爬取時使用的 Cookies,為字典格式 。

• connect timeout

connect timeout是在初始化連線時的最長等待時間,它預設是 20秒。

• timeout

timeout 是抓取網頁時的最長等待時間,它預設是 120秒。

• allow redirects

allow redirects 確定是否自動處理重定向,它預設是 True。

• proxy

proxy是爬取時使用的代理,它支援使用者名稱密碼的配置,格式為 username:password@hostname:port,

• fetch_type

fetch_type開啟 PhantomJS渲染 。如果遇到 JavaScript渲染的頁面,指定此欄位即可實現 PhantomJS的對接,pyspider將會使用 PhantomJS 進行網頁的抓取,

• js_script

js script 是頁面載入完畢後執行的 JavaScript指令碼

• js_run_at

JavaScript指令碼執行的位置,是在頁面節點開頭還是結尾 , 預設是結尾, 即 document-end。

• js_viewport_width/js_viewport_height

js_viewport_width/js_viewport_height是 JavaScript渲染頁面時的視窗大小。

• load_images

load_images在載入 JavaScript頁面時確定是否載入圖片,它預設是否。

• save

save 引數非常有用,可以在不同的方法之 間傳遞引數

• cancel
cancel是取消任務,如果一個任務是 ACTIVE狀態的, 則需要將 force_update設定為 True。

• force_ update

即使任務處於 ACTIVE狀態,那也會強制更新狀態。

 
任務區分:

pyspider判斷兩個任務是否是重複 的是使用的是該任務對應的 URL 的 MD5 值作為任務的唯一ID,如果ID 相 同,那麼兩個任務就會判定為相同,其中一個就不會爬取了 。 很多情況下請求的連結叮能是同一個,但是POST的引數不同。 這時可以重寫task_id()方法,改變這個ID的計算方式來實現不同任務的區分,

定時爬取

1 @every(minutes=24 * 60) 
2 def on_start(self):
3     for url in urllist:
4         self.crawl(url, callback=self.index_page)

 

轉載於:https://www.cnblogs.com/chengchengaqin/p/9808006.html

相關文章