Python網絡爬蟲精要

目的css

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

本文所用到的第三方庫以下: requests, parsel, seleniummysql

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

網絡爬蟲是什麼github

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

如何爬取網站信息ajax

寫爬蟲以前,咱們必須確保可以爬取目標網站的信息。sql

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

  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

相關文章
相關標籤/搜索