當前位置:
首頁 > 知識 > Python網路爬蟲精要

Python網路爬蟲精要


程序員大咖

點擊右側關注,免費進階高級!





alphardex,Pythonista && Otaku,努力轉行中的一位測繪人員。

地址:zhihu.com/people/ban-zai-liu-shang


目的


學習如何從互聯網上獲取數據。數據科學必須掌握的技能之一。


本文所用到的第三方庫如下: requests, parsel, selenium

requests負責向網頁發送HTTP請求並得到響應,parsel負責解析響應字元串,selenium負責JavaScript的渲染。


網路爬蟲是什麼


網路爬蟲是一種按照一定的規則,自動地抓取網站信息的程序或者腳本。


如何爬取網站信息

寫爬蟲之前,我們必須確保能夠爬取目標網站的信息。


不過在此之前必須弄清以下三個問題:




  1. 網站是否已經提供了api



  2. 網站是靜態的還是動態的



  3. 網站是否有反爬的對策


情形1:開放api的網站


一個網站倘若開放了api,那你就可以直接GET到它的json數據。


比如xkcd的about頁就提供了api供你下載

import

 requests
requests.

get

(

"https://xkcd.com/614/info.0.json"

).json()

那麼如何判斷一個網站是否開放api呢?有3種方法:




  1. 在站內尋找api入口



  2. 用搜索引擎搜索「某網站 api」



  3. 抓包。有的網站雖然用到了ajax(比如果殼網的瀑布流文章),但是通過抓包還是能夠獲取XHR里的json數據的。


怎麼抓包:F12 - Network - F5刷新即可 | 或者用fiddle等工具也可以

情形2:不開放api的網站


如果此網站是靜態頁面,那麼你就可以用requests庫發送請求,再用HTML解析庫(lxml、parsel等)來解析響應的text


解析庫強烈推薦parsel,不僅語法和css選擇器類似,而且速度也挺快,Scrapy用的就是它。


你需要了解一下css選擇器的語法(xpath也行),並且學會看網頁的審查元素。


比如獲取konachan的所有原圖鏈接

from

 parsel import Selector
res = requests.

get

(

"https://konachan.com/post")


tree = Selector(

text

=res.

text

)
imgs = tree.css(

"a.directlink::attr(href)").extract()



如果此網站是動態頁面,先用selenium來渲染JS,再用HTML解析庫來解析driver的page_source。


比如獲取hitomi.la的數據(這裡把chrome設置成了無頭模式)

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)

driver.get("https://hitomi.la/type/gamecg-all-1.html")


tree = Selector(text=driver.page_source)
gallery_content = tree.css(".gallery-content > div")

情形3:反爬的網站


目前的反爬策略常見的有:驗證碼、登錄、封ip等。


驗證碼:利用打碼平台破解(如果硬上的話用opencv或keras訓練圖)


登錄:利用requests的post或者selenium模擬用戶進行模擬登陸


封ip:買些代理ip(免費ip一般都不管用),requests中傳入proxies參數即可


其他防反爬方法:偽裝User-Agent,禁用cookies等


推薦用fake-useragent來偽裝User-Agent

from fake_useragent import UserAgent
headers = {"User-Agent": UserAgent().random}
res = requests.get(url, headers=headers)

如何編寫結構化的爬蟲


如果能成功地爬取網站信息,那麼你已經成功了一大半。


其實爬蟲的架構很簡單,無非就是創造一個tasklist,對tasklist里的每一個task調用crawl函數。


大多數網頁的url構造都是有規律的,你只需根據它用列表推倒式來構造出tasklist對於那些url不變的動態網頁,先考慮抓包,不行再用selenium點擊下一頁
如果追求速度的話,可以考慮用concurrent.futures或者asyncio等庫。

import

 requests

from

 parsel 

import

 Selector

from

 concurrent 

import

 futures

domain = 

"https://www.doutula.com"

def

 

crawl(url)

:


    res = requests.get(url)
    tree = Selector(text=res.text)
    imgs = tree.css(

"img.lazy::attr(data-original)"

).extract()
    

# save the imgs ...

if

 __name__ == 

"__main__"

:
    tasklist = [

f"

{domain}

/article/list/?page=

{i}

"

 

for

 i 

in

 range(

1

551

)]
    

with

 futures.ThreadPoolExecutor(

50

as

 executor:
        executor.map(crawl, tasklist)

數據存儲的話,看你的需求,一般都是存到資料庫中,只要熟悉對應的驅動即可。


常用的資料庫驅動有:pymysql(MySQL),pymongo(MongoDB)


如果你需要框架的話


文章讀到這裡,你應該對爬蟲的基本結構有了一個清晰的認識,這時你可以去上手框架了。


輕量級框架(looter):https://github.com/alphardex/looter


工業級框架(scrapy):https://github.com/scrapy/scrapy


【點擊成為源碼大神】

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發 的精彩文章:

使用Python自動生成報表以郵件發送
婚禮小記:用Twilio,Python和Google打造我的自動化婚禮

TAG:Python開發 |