Python 構建一個簡單爬蟲系統 (一)
本文通過 requests beautifulsoup re 等 Python的模塊, 嘗試構建一個微型的爬蟲系統,本文採用 Python 3 的版本,本文是第一篇,主要介紹一個網頁的簡單抓取和解析。
目錄
- 0x00·簡介
- 0x01·簡單抓取
- 0x02·解析網頁
0x00 簡介
- requests 作為優秀的 Python 第三方的模塊,當邂逅了之後,你就會向 urllib say goodbye 了, 本文會介紹一些 requests 的具體的使用方法。
beautifulsoup 作為常用的解析網頁的第三方的模塊,通過 「lxml」 作為解析器,可以達到速度和兼容性的平衡.
當然 xpath 也是一個很好的選擇。re 還是無處不在的顯示其強大的生命力。在了解 requests Beautifulsoup4 的用法的基礎上,一步步教你怎麼構建一個簡單的小型爬蟲系統,
本文是對 requests Beautifulsoup4 的一個簡單的綜合應用,關於這兩 Python 優秀的第三方模塊的使用方法,可以看本文最後我給的參考文檔
0x01 簡單抓取
抓取一個網頁並且把內容保存到本地
import requestsnndef get_html(url):n html = requests.get(url)n with open(content.html, wb) as fw:n fw.write(html.content)n fw.close()nif __name__ == __main__:n url = "Example Domain"n get_data(url)n
可是你會發現,大多數情況,這個代碼是沒法工作的,網站會對 request header 做一些限制,
def get_html(url):n headers = {n User-Agent: ""Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36""n }n html = requests.get(url, headers=headers)n with open(content.html, wb) as fw:n fw.write(html.content)n fw.close()nnif __name__ == __main__:n url = "Example Domain"n get_html(url)n
主要是後面的方法,我們假裝好像瀏覽器的樣子,
還有些網站需要檢測 Request headers 裡面的 Refer host 等欄位,我們會在後面講到但是 0x01-1 的代碼,還是不夠健壯,因為,我們不知道請求是否成功了,如果最後保存到本地的,是一堆 404 的頁面,顯然是一件很讓人沮喪的事情,我們在把代碼改下,加上一個請求是否成功的代碼。http 請求狀態有很多種,大多數情況下 200 是我們理想中的狀態,
def get_data(url):n headers = {n "User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"n }n html = requests.get(url, headers=headers)n if html.status_code == 200:n print(url, @ok200, str(time.ctime()))n with open(content.html, wb) as fw:n fw.write(html.content)n fw.close()n else:n print(url, wrong, str(time.ctime()))nnif __name__ == __main__:n url = "Example Domain"n get_data(url)n
我們用 requests 的一個 status_code 方法來判斷是否訪問成功,然後使用 print 一下,相當於列印日誌了,當我們做大規模抓取的時候,print 顯然不是一個很好的選擇,Python 的 logging 模塊能夠更好的勝任這項工作,為了方便起見,我們暫時使用簡單直接粗暴的 print 來做代替 logging 的工作
由於網路原因,可能會出現訪問超時的問題,為了讓代碼更健壯,我們可以設置 timeout, 同時,如果確定網頁不需要重定向, 可以設置 allow_redirects=False
def get_data(url):n headers = {n "User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"n }n try:n html = requests.get(url, headers=headers, allow_redirects=Fasle, timeout=3)n if html.status_code == 200:n print(url, @ok200, str(time.ctime()))n with open(content.html, wb) as fw:n fw.write(html.content)n fw.close()n else:n print(url, wrong, str(time.ctime()))n except Exception as e:n print(url, e, str(time.ctime()))nnif __name__ == __main__:n url = "Example Domain"n get_data(url)n
至此,我們完成了一個網頁的抓取,並且做了相關的異常處理。
0x02 解析網頁
本節說明下,通過 re 和 beautifulsoup 的組合來解析網頁
1. re (正則表達式) 提取網頁
經常用的是貪婪匹配和非貪婪匹配,還有就是單行匹配還是全文匹配
最常用的方法是 re.findall 還有括弧的使用例如
import rentext = """Sxchaoinfo@EgithubEn xchaoinfo@wechatn xchaoinfo@zhihuE"""n
- 模式一
# 加上 re.S 代表是全文匹配npa = rS.*?Enre.findall(pa, text) -> 返回的是["Sxchaoinfo@E",]nre.findall(pa, text, re.S) -> 返回的是["Sxchaoinfo@E",]n
- 模式二```pythonpa = r』S.*E』
re.findall(pa, text) -> 返回的是[『Sxchaoinfo@EgithubE』, ]
re.findall(pa, text, re.S) -> 返回的是
[『Sxchaoinfo@EgithubEn xchaoinfo@wechatn xchaoinfo@zhihuE』, ]- 模式三n```pythonnpa = rS(.*?)Enre.findall(pa, text) -> 返回的是[xchaoinfo@,]n
更佳詳細的 re(正則表達式) 的使用方法,請參考文檔獲取其他網站的教程
2. beautifulsoup 提取網頁
Beautifulsoup 解析網頁的時候推薦使用 lxml作為解析器,雖然 lxml 的安裝可能會花費您一點時間,其他解析器的選擇,可以參考官方的文檔
最常用的方法是from bs4 import BeautifulSoupnn# 獲取頁面所有的 url 鏈接nsoup = BeautifulSoup(html_content, lxml)nahref = soup.findAll(a)nfor a in ahref:n print(a[href])n
參考文檔
- Requests: HTTP for Humans
- requests 中文文檔
- BeautifulSoup Documentation
- BeautifulSoup 中文文檔
微信公眾號: xchaoinfo
推薦閱讀:
※怎樣將一個24的n次方複雜度的計算優化?
※為機器學習愛好者推薦一本書《貝葉斯方法:概率編程與貝葉斯推斷》
※ELEMENTARY.03.First Word
※【書籍推薦】關於機器學習、深度學習等數據科學的最新書籍(可下載)
※金融工程現在用python多嗎?
TAG:Python |