您好,登錄后才能下訂單哦!
小編給大家分享一下關(guān)于pyspider的用法,相信大部分人都還不怎么了解,因此分享這篇文章給大家學(xué)習(xí),希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去學(xué)習(xí)方法吧!
pyspider 用法詳解
前面我們了解了 pyspider 的基本用法,我們通過非常少的代碼和便捷的可視化操作就完成了一個爬蟲的編寫,本節(jié)我們來總結(jié)一下它的詳細用法。
1. 命令行
上面的實例通過如下命令啟動 pyspider:
pyspider all
命令行還有很多可配制參數(shù),完整的命令行結(jié)構(gòu)如下所示:
pyspider [OPTIONS] COMMAND [ARGS]
其中,OPTIONS 為可選參數(shù),它可以指定如下參數(shù)。
Options: -c, --config FILENAME 指定配置文件名稱 --logging-config TEXT 日志配置文件名稱,默認: pyspider/pyspider/logging.conf --debug 開啟調(diào)試模式 --queue-maxsize INTEGER 隊列的最大長度 --taskdb TEXT taskdb 的數(shù)據(jù)庫連接字符串,默認: sqlite --projectdb TEXT projectdb 的數(shù)據(jù)庫連接字符串,默認: sqlite --resultdb TEXT resultdb 的數(shù)據(jù)庫連接字符串,默認: sqlite --message-queue TEXT 消息隊列連接字符串,默認: multiprocessing.Queue --phantomjs-proxy TEXT PhantomJS 使用的代理,ip:port 的形式 --data-path TEXT 數(shù)據(jù)庫存放的路徑 --version pyspider 的版本 --help 顯示幫助信息
例如,-c 可以指定配置文件的名稱,這是一個常用的配置,配置文件的樣例結(jié)構(gòu)如下所示:
{ "taskdb": "mysql+taskdb://username:password@host:port/taskdb", "projectdb": "mysql+projectdb://username:password@host:port/projectdb", "resultdb": "mysql+resultdb://username:password@host:port/resultdb", "message_queue": "amqp://username:password@host:port/%2F", "webui": { "username": "some_name", "password": "some_passwd", "need-auth": true } }
如果要配置 pyspider WebUI 的訪問認證,可以新建一個 pyspider.json,內(nèi)容如下所示:
{ "webui": { "username": "root", "password": "123456", "need-auth": true } }
這樣我們通過在啟動時指定配置文件來配置 pyspider WebUI 的訪問認證,用戶名為 root,密碼為 123456,命令如下所示:
pyspider -c pyspider.json all
運行之后打開:http://localhost:5000/,頁面如 12-26 所示:
圖 12-26 運行頁面
也可以單獨運行 pyspider 的某一個組件。
運行 Scheduler 的命令如下所示:
pyspider scheduler [OPTIONS]
運行時也可以指定各種配置,參數(shù)如下所示:
Options: --xmlrpc /--no-xmlrpc --xmlrpc-host TEXT --xmlrpc-port INTEGER --inqueue-limit INTEGER 任務(wù)隊列的最大長度,如果滿了則新的任務(wù)會被忽略 --delete-time INTEGER 設(shè)置為 delete 標記之前的刪除時間 --active-tasks INTEGER 當(dāng)前活躍任務(wù)數(shù)量配置 --loop-limit INTEGER 單輪最多調(diào)度的任務(wù)數(shù)量 --scheduler-cls TEXT Scheduler 使用的類 --help 顯示幫助信息
運行 Fetcher 的命令如下所示:
pyspider fetcher [OPTIONS]
參數(shù)配置如下所示:
Options: --xmlrpc /--no-xmlrpc --xmlrpc-host TEXT --xmlrpc-port INTEGER --poolsize INTEGER 同時請求的個數(shù) --proxy TEXT 使用的代理 --user-agent TEXT 使用的 User-Agent --timeout TEXT 超時時間 --fetcher-cls TEXT Fetcher 使用的類 --help 顯示幫助信息
運行 Processer 的命令如下所示:
pyspider processor [OPTIONS]
參數(shù)配置如下所示:
Options: --processor-cls TEXT Processor 使用的類 --help 顯示幫助信息
運行 WebUI 的命令如下所示:
pyspider webui [OPTIONS]
參數(shù)配置如下所示:
Options: --host TEXT 運行地址 --port INTEGER 運行端口 --cdn TEXT JS 和 CSS 的 CDN 服務(wù)器 --scheduler-rpc TEXT Scheduler 的 xmlrpc 路徑 --fetcher-rpc TEXT Fetcher 的 xmlrpc 路徑 --max-rate FLOAT 每個項目最大的 rate 值 --max-burst FLOAT 每個項目最大的 burst 值 --username TEXT Auth 驗證的用戶名 --password TEXT Auth 驗證的密碼 --need-auth 是否需要驗證 --webui-instance TEXT 運行時使用的 Flask 應(yīng)用 --help 顯示幫助信息
這里的配置和前面提到的配置文件參數(shù)是相同的。如果想要改變 WebUI 的端口為 5001,單獨運行如下命令:
pyspider webui --port 5001
或者可以將端口配置到 JSON 文件中,配置如下所示:
{ "webui": {"port": 5001} }
使用如下命令啟動同樣可以達到相同的效果:
pyspider -c pyspider.json webui
這樣就可以在 5001 端口上運行 WebUI 了。
2. crawl() 方法
在前面的例子中,我們使用 crawl() 方法實現(xiàn)了新請求的生成,但是只指定了 URL 和 Callback。這里將詳細介紹一下 crawl() 方法的參數(shù)配置。
url
url 是爬取時的 URL,可以定義為單個 URL 字符串,也可以定義成 URL 列表。
callback
callback 是回調(diào)函數(shù),指定了該 URL 對應(yīng)的響應(yīng)內(nèi)容用哪個方法來解析,如下所示:
def on_start(self): self.crawl('http://scrapy.org/', callback=self.index_page)
這里指定了 callback 為 index_page,就代表爬取 http://scrapy.org/ 鏈接得到的響應(yīng)會用 index_page() 方法來解析。
index_page() 方法的第一個參數(shù)是響應(yīng)對象,如下所示:
def index_page(self, response): pass
方法中的 response 參數(shù)就是請求上述 URL 得到的響應(yīng)對象,我們可以直接在 index_page() 方法中實現(xiàn)頁面的解析。
age
age 是任務(wù)的有效時間。如果某個任務(wù)在有效時間內(nèi)且已經(jīng)被執(zhí)行,則它不會重復(fù)執(zhí)行,如下所示:
def on_start(self): self.crawl('http://www.example.org/', callback=self.callback, age=10*24*60*60)
或者可以這樣設(shè)置:
@config(age=10 * 24 * 60 * 60) def callback(self): pass
默認的有效時間為 10 天。
priority
priority 是爬取任務(wù)的優(yōu)先級,其值默認是 0,priority 的數(shù)值越大,對應(yīng)的請求會越優(yōu)先被調(diào)度,如下所示:
def index_page(self): self.crawl('http://www.example.org/page.html', callback=self.index_page) self.crawl('http://www.example.org/233.html', callback=self.detail_page, priority=1)
第二個任務(wù)會優(yōu)先調(diào)用,233.html 這個鏈接優(yōu)先爬取。
exetime
exetime 參數(shù)可以設(shè)置定時任務(wù),其值是時間戳,默認是 0,即代表立即執(zhí)行,如下所示:
import time def on_start(self): self.crawl('http://www.example.org/', callback=self.callback, exetime=time.time()+30*60)
這樣該任務(wù)會在 30 分鐘之后執(zhí)行。
retries
retries 可以定義重試次數(shù),其值默認是 3。
itag
itag 參數(shù)設(shè)置判定網(wǎng)頁是否發(fā)生變化的節(jié)點值,在爬取時會判定次當(dāng)前節(jié)點是否和上次爬取到的節(jié)點相同。如果節(jié)點相同,則證明頁面沒有更新,就不會重復(fù)爬取,如下所示:
def index_page(self, response): for item in response.doc('.item').items(): self.crawl(item.find('a').attr.url, callback=self.detail_page, itag=item.find('.update-time').text())
在這里設(shè)置了更新時間這個節(jié)點的值為 itag,在下次爬取時就會首先檢測這個值有沒有發(fā)生變化,如果沒有變化,則不再重復(fù)爬取,否則執(zhí)行爬取。
auto_recrawl
當(dāng)開啟時,爬取任務(wù)在過期后會重新執(zhí)行,循環(huán)時間即定義的 age 時間長度,如下所示:
def on_start(self): self.crawl('http://www.example.org/', callback=self.callback, age=5*60*60, auto_recrawl=True)
這里定義了 age 有效期為 5 小時,設(shè)置了 auto_recrawl 為 True,這樣任務(wù)就會每 5 小時執(zhí)行一次。
method
method 是 HTTP 請求方式,它默認是 GET。如果想發(fā)起 POST 請求,可以將 method 設(shè)置為 POST。
params
我們可以方便地使用 params 來定義 GET 請求參數(shù),如下所示:
def on_start(self): self.crawl('http://httpbin.org/get', callback=self.callback, params={'a': 123, 'b': 'c'}) self.crawl('http://httpbin.org/get?a=123&b=c', callback=self.callback)
這里兩個爬取任務(wù)是等價的。
data
data 是 POST 表單數(shù)據(jù)。當(dāng)請求方式為 POST 時,我們可以通過此參數(shù)傳遞表單數(shù)據(jù),如下所示:
def on_start(self): self.crawl('http://httpbin.org/post', callback=self.callback, method='POST', data={'a': 123, 'b': 'c'})
files
files 是上傳的文件,需要指定文件名,如下所示:
def on_start(self): self.crawl('http://httpbin.org/post', callback=self.callback, method='POST', files={field: {filename: 'content'}})
user_agent
user_agent 是爬取使用的 User-Agent。
headers
headers 是爬取時使用的 Headers,即 Request Headers。
cookies
cookies 是爬取時使用的 Cookies,為字典格式。
connect_timeout
connect_timeout 是在初始化連接時的最長等待時間,它默認是 20 秒。
timeout
timeout 是抓取網(wǎng)頁時的最長等待時間,它默認是 120 秒。
allow_redirects
allow_redirects 確定是否自動處理重定向,它默認是 True。
validate_cert
validate_cert 確定是否驗證證書,此選項對 HTTPS 請求有效,默認是 True。
proxy
proxy 是爬取時使用的代理,它支持用戶名密碼的配置,格式為 username:password@hostname:port,如下所示:
def on_start(self): self.crawl('http://httpbin.org/get', callback=self.callback, proxy='127.0.0.1:9743')
也可以設(shè)置 craw_config 來實現(xiàn)全局配置,如下所示:
class Handler(BaseHandler): crawl_config = {'proxy': '127.0.0.1:9743'}
fetch_type
fetch_type 開啟 PhantomJS 渲染。如果遇到 JavaScript 渲染的頁面,指定此字段即可實現(xiàn) PhantomJS 的對接,pyspider 將會使用 PhantomJS 進行網(wǎng)頁的抓取,如下所示:
def on_start(self): self.crawl('https://www.taobao.com', callback=self.index_page, fetch_type='js')
這樣我們就可以實現(xiàn)淘寶頁面的抓取了,得到的結(jié)果就是瀏覽器中看到的效果。
js_script
js_script 是頁面加載完畢后執(zhí)行的 JavaScript 腳本,如下所示:
def on_start(self): self.crawl('http://www.example.org/', callback=self.callback, fetch_type='js', js_script=''' function() {window.scrollTo(0,document.body.scrollHeight); return 123; } ''')
頁面加載成功后將執(zhí)行頁面混動的 JavaScript 代碼,頁面會下拉到最底部。
js_run_at
js_run_at 代表 JavaScript 腳本運行的位置,是在頁面節(jié)點開頭還是結(jié)尾,默認是結(jié)尾,即 document-end。
js_viewport_width/js_viewport_height
js_viewport_width/js_viewport_height 是 JavaScript 渲染頁面時的窗口大小。
load_images
load_images 在加載 JavaScript 頁面時確定是否加載圖片,它默認是否。
save
save 參數(shù)非常有用,可以在不同的方法之間傳遞參數(shù),如下所示:
def on_start(self): self.crawl('http://www.example.org/', callback=self.callback, save={'page': 1}) def callback(self, response): return response.save['page']
這樣,在 on_start() 方法中生成 Request 并傳遞額外的參數(shù) page,在回調(diào)函數(shù)里可以通過 response 變量的 save 字段接收到這些參數(shù)值。
cancel
cancel 是取消任務(wù),如果一個任務(wù)是 ACTIVE 狀態(tài)的,則需要將 force_update 設(shè)置為 True。
force_update
即使任務(wù)處于 ACTIVE 狀態(tài),那也會強制更新狀態(tài)。
以上便是 crawl() 方法的參數(shù)介紹,更加詳細的描述可以參考:http://docs.pyspider.org/en/latest/apis/self.crawl/。
3. 任務(wù)區(qū)分
在 pyspider 判斷兩個任務(wù)是否是重復(fù)的是使用的是該任務(wù)對應(yīng)的 URL 的 MD5 值作為任務(wù)的唯一 ID,如果 ID 相同,那么兩個任務(wù)就會判定為相同,其中一個就不會爬取了。很多情況下請求的鏈接可能是同一個,但是 POST 的參數(shù)不同。這時可以重寫 task_id() 方法,改變這個 ID 的計算方式來實現(xiàn)不同任務(wù)的區(qū)分,如下所示:
import json from pyspider.libs.utils import md5string def get_taskid(self, task): return md5string(task['url']+json.dumps(task['fetch'].get('data', '')))
這里重寫了 get_taskid() 方法,利用 URL 和 POST 的參數(shù)來生成 ID。這樣一來,即使 URL 相同,但是 POST 的參數(shù)不同,兩個任務(wù)的 ID 就不同,它們就不會被識別成重復(fù)任務(wù)。
4. 全局配置
pyspider 可以使用 crawl_config 來指定全局的配置,配置中的參數(shù)會和 crawl() 方法創(chuàng)建任務(wù)時的參數(shù)合并。如要全局配置一個 Headers,可以定義如下代碼:
class Handler(BaseHandler): crawl_config = { 'headers': {'User-Agent': 'GoogleBot',} }
5. 定時爬取
我們可以通過 every 屬性來設(shè)置爬取的時間間隔,如下所示:
@every(minutes=24 * 60) def on_start(self): for url in urllist: self.crawl(url, callback=self.index_page)
這里設(shè)置了每天執(zhí)行一次爬取。
在上文中我們提到了任務(wù)的有效時間,在有效時間內(nèi)爬取不會重復(fù)。所以要把有效時間設(shè)置得比重復(fù)時間更短,這樣才可以實現(xiàn)定時爬取。
例如,下面的代碼就無法做到每天爬?。?/p>
@every(minutes=24 * 60) def on_start(self): self.crawl('http://www.example.org/', callback=self.index_page) @config(age=10 * 24 * 60 * 60) def index_page(self): pass
這里任務(wù)的過期時間為 10 天,而自動爬取的時間間隔為 1 天。當(dāng)?shù)诙螄L試重新爬取的時候,pyspider 會監(jiān)測到此任務(wù)尚未過期,便不會執(zhí)行爬取,所以我們需要將 age 設(shè)置得小于定時時間。
6. 項目狀態(tài)
每個項目都有 6 個狀態(tài),分別是 TODO、STOP、CHECKING、DEBUG、RUNNING、PAUSE。
TODO:它是項目剛剛被創(chuàng)建還未實現(xiàn)時的狀態(tài)。
STOP:如果想停止某項目的抓取,可以將項目的狀態(tài)設(shè)置為 STOP。
CHECKING:正在運行的項目被修改后就會變成 CHECKING 狀態(tài),項目在中途出錯需要調(diào)整的時候會遇到這種情況。
DEBUG/RUNNING:這兩個狀態(tài)對項目的運行沒有影響,狀態(tài)設(shè)置為任意一個,項目都可以運行,但是可以用二者來區(qū)分項目是否已經(jīng)測試通過。
PAUSE:當(dāng)爬取過程中出現(xiàn)連續(xù)多次錯誤時,項目會自動設(shè)置為 PAUSE 狀態(tài),并等待一定時間后繼續(xù)爬取。
7. 抓取進度
在抓取時,可以看到抓取的進度,progress 部分會顯示 4 個進度條,如圖 12-27 所示。
圖 12-27 抓取進度
progress 中的 5m、1h、1d 指的是最近 5 分、1 小時、1 天內(nèi)的請求情況,all 代表所有的請求情況。
藍色的請求代表等待被執(zhí)行的任務(wù),綠色的代表成功的任務(wù),黃色的代表請求失敗后等待重試的任務(wù),紅色的代表失敗次數(shù)過多而被忽略的任務(wù),從這里我們可以直觀看到爬取的進度和請求情況。
8. 刪除項目
pyspider 中沒有直接刪除項目的選項。如要刪除任務(wù),那么將項目的狀態(tài)設(shè)置為 STOP,將分組的名稱設(shè)置為 delete,等待 24 小時,則項目會自動刪除。
以上是關(guān)于pyspider的用法的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。