repo: github.com/alphardex/p…
如今,網上的爬蟲教程可謂是氾濫成災了,從urllib開始講,最後才講到requests和selenium這類高階庫,實際上,根本就不必這麼費心地去了解這麼多無謂的東西的。只需記住爬蟲總共就三大步驟:發起請求——解析資料——儲存資料,這樣就足以寫出最基本的爬蟲了。諸如像Scrapy這樣的框架,可以說是整合了爬蟲的一切,但是新人可能會用的不怎麼順手,看教程可能還會踩各種各樣的坑,而且Scrapy本身體積也有點大。因此,本人決定親手寫一個輕量級的爬蟲框架————looter,裡面整合了除錯和爬蟲模板這兩個核心功能,利用looter,你就能迅速地寫出一個高效的爬蟲。另外,本專案的函式文件也相當完整,如果有不明白的地方可以自行閱讀原始碼(一般都是按Ctrl+左鍵或者F12)。
安裝
$ pip install looter
複製程式碼
僅支援Python3.6及以上版本。
快速開始
讓我們先來擼一個非常簡單的圖片爬蟲:首先,用shell獲取網站
$ looter shell https://konachan.com/post
複製程式碼
然後用1行程式碼將圖片的url提取出來
>>> imgs = tree.css('a.directlink::attr(href)').extract()
複製程式碼
或者用另一種方式提取
>>> imgs = links(res, pattern=r'.*/(jpeg|image)/.*')
複製程式碼
將url儲存到本地
>>> Path('konachan.txt').write_text('\n'.join(imgs))
複製程式碼
可以通過wget等下載工具將圖片下載下來
$ wget -i konachan.txt
複製程式碼
如果想要看更多的爬蟲例子,猛戳這裡
工作流
如果你想迅速擼出一個爬蟲,那麼你可以用looter提供的模板來自動生成一個
$ looter genspider <name> [--async]
複製程式碼
async是一個備用的選項,它使得生成的爬蟲核心用asyncio而非執行緒池。
在生成的模板中,你可以自定義domain和tasklist這兩個變數。
什麼是tasklist?實際上它就是你想要抓取的頁面的所有連結。
以konachan.com為例,你可以使用列表推導式來建立自己的tasklist:
domain = 'https://konachan.com'
tasklist = [f'{domain}/post?page={i}' for i in range(1, 9777)]
複製程式碼
然後你就要定製你的crawl函式,這是爬蟲的核心部分。
def crawl(url):
tree = lt.fetch(url)
items = tree.css('ul li')
for item in items:
data = {}
# data[...] = item.css(...)
pprint(data)
複製程式碼
在大多數情況下,你所要抓取的內容是一個列表(也就是HTML中的ul或ol標籤),可以用css選擇器將它們儲存為items變數。
然後,你只需使用for迴圈來迭代它們,並抽取你想要的資料,將它們儲存到dict中。
但是,在你寫完這個爬蟲之前,最好用looter提供的shell來除錯一下你的css程式碼是否正確。(目前已整合ptpython,一個支援自動補全的REPL)
>>> items = tree.css('ul li')
>>> item = items[0]
>>> item.css(anything you want to crawl)
# 注意程式碼的輸出是否正確!
複製程式碼
除錯完成後,你的爬蟲自然也就完成了。怎麼樣,是不是很簡單:)
函式
looter為使用者提供了一些比較實用的函式。
view
在爬取頁面前,你最好確認一下頁面的渲染是否是你想要的
>>> view(url)
複製程式碼
links
獲取網頁的所有連結
>>> links(res) # 獲取所有連結
>>> links(res, search='...') # 查詢指定連結
>>> links(res, pattern=r'...') # 正則查詢連結
複製程式碼
save
將所得結果儲存為資料檔案,支援按鍵值排序(sort_by)和去重(no_duplicate)
>>> total = [...]
>>> save(total, sort_by='key', no_duplicate=True)
複製程式碼
預設儲存為json格式,如果想儲存為csv只需把檔名字尾改為csv,但必須保證pandas這個包已經安裝好。
套路總結
- 通過抓包,確認網站是否開放了api,如果有,直接抓取api;如果沒有,進入下一步
- 確認網站是靜態的還是動態的(有無JS載入,是否需要登入等),方法有:肉眼觀察、抓包、looter的view函式
- 若網站是靜態網頁,直接用looter genspider生成爬蟲模板,再配合looter shell寫出爬蟲即可
- 若網站是動態網頁,先抓包試試,嘗試獲取所有ajax生成的api連結;如果沒有api,則進入下一步
- 有的網站並不會直接暴露ajax的api連結,這時就需要你自行根據規律,構造出api連結
- 如果上一步無法成功,那麼就只好用requestium來渲染JS,抓取頁面
- 至於模擬登入、代理IP、驗證碼、分散式等問題,由於範圍太廣,請自行解決
- 如果你的爬蟲專案被要求用Scrapy,那麼你也可以將looter的解析程式碼無痛地複製到Scrapy上(畢竟都用了parsel)
掌握了以上的套路,再難爬的網站也難不倒你。