1. 前言
大家好,我是安果!
今天再推薦一款小衆輕量級的爬蟲庫:MechanicalSoup
MechanicalSoup,也是一款爬蟲神器!它使用純 Python 開發,底層基於 Beautiful Soup 和 Requests,實現網頁自動化及數據爬取
項目地址:
https://github.com/MechanicalSoup/MechanicalSoup
2. 安裝及常見用法
首先安裝依賴庫
# 安裝依賴庫
pip3 install MechanicalSoup
常見操作如下:
2-1 實例化瀏覽器對象
使用 mechanicalsoup 內置的 StatefulBrowser() 方法可以實例化一個瀏覽器對象
import mechanicalsoup
# 實例化瀏覽器對象
browser = mechanicalsoup.StatefulBrowser(user_agent='MechanicalSoup')
PS:實例化的同時,參數可以執行 User Agent 及數據解析器,默認解析器爲 lxml
2-2 打開網站及返回值
使用瀏覽器實例對象的 open(url) 即可以打開一個網頁,返回值類型爲:requests.models.Response
# 打開一個網站
result = browser.open("http://httpbin.org/")
print(result)
# 返回值類型:requests.models.Response
print(type(result))
通過返回值可以發現,使用瀏覽器對象打開網站相當於使用 requests 庫對網站進行了一次請求
2-3 網頁元素及當前 URL
使用瀏覽器對象的「url」屬性可以獲取當前頁面的 URL 地址;瀏覽器的「 page 」屬性用於獲取頁面的所有網頁元素內容
由於 MechanicalSoup 底層基於 BS4,因此 BS4 的語法都適用於 MechanicalSoup
# 當前網頁URL地址
url = browser.url
print(url)
# 查看網頁的內容
page_content = browser.page
print(page_content)
2-4 表單操作
瀏覽器對象內置的 select_form(selector) 方法用於獲取當前頁面的 Form 表單元素
如果當前網頁只有一個 Form 表單,則參數可以省略
# 獲取當前網頁中某個表單元素
# 利用action來過濾
browser.select_form('form[action="/post"]')
# 如果網頁只有一個Form表單,參數可以省略
browser.select_form()
form.print_summary() 用於將表單內全部元素打印出來
form = browser.select_form()
# 打印當前選定表單內部全部元素
form.print_summary()
至於表單內的 input 普通輸入框、單選框 radio、複選框 checkbox
# 1、普通輸入框
# 通過input的name屬性直接設置值,模擬輸入
browser["norm_input"] = "普通輸入框的值"
# 2、單元框radio
# 通過name屬性值,選擇某一個value值
# <input name="size" type="radio" value="small"/>
# <input name="size" type="radio" value="medium"/>
# <input name="size" type="radio" value="large"/>
browser["size"] = "medium"
# 3、複選框checkbox
# 通過name屬性值,選擇某幾個值
# <input name="topping" type="checkbox" value="bacon"/>
# <input name="topping" type="checkbox" value="cheese"/>
# <input name="topping" type="checkbox" value="onion"/>
# <input name="topping" type="checkbox" value="mushroom"/>
browser["topping"] = ("bacon", "cheese")
瀏覽器對象的 submit_selected(btnName) 方法用於提交表單
需要注意的是,提交表單後的返回值類型爲:requests.models.Response
# 提交表單(模擬單擊“提交”按鈕)
response = browser.submit_selected()
print("結果爲:",response.text)
# 結果類型:requests.models.Response
print(type(response))
2-5 調試利器
瀏覽器對象 browser 提供了一個方法:launch_browser()
用於啓動一個真實的 Web 瀏覽器,可視化展示當前網頁的狀態,在自動化操作過程中非常直觀有用
PS:它不會真實打開網頁,而是創建一個包含頁面內容的臨時頁面,並將瀏覽器指向這個文件
更多功能可以參考:
https://mechanicalsoup.readthedocs.io/en/stable/tutorial.html
3. 實戰一下
我們以「 微信文章搜索,爬取文章標題及鏈接地址 」爲例
3-1 打開目標網站,並指定隨機 UA
由於很多網站對 User Agent 做了反爬,因此這裏隨機生成了一個 UA,並設置進去
PS:從 MechanicalSoup 源碼會發現,UA 相當於設置到 Requests 的請求頭中
import mechanicalsoup
from faker import Factory
home_url = 'https://weixin.sogou.com/'
# 實例化一個瀏覽器對象
# user_agent:指定UA
f = Factory.create()
ua = f.user_agent()
browser = mechanicalsoup.StatefulBrowser(user_agent=ua)
# 打開目標網站
result = browser.open(home_url)
3-2 表單提交,搜索一次
使用瀏覽器對象獲取網頁中的表單元素,然後給表單中的 input 輸入框設置值,最後模擬表單提交
# 獲取表單元素
browser.select_form()
# 打印表單內所有元素信息
# browser.form.print_summary()
# 根據name屬性,填充內容
browser["query"] = "Python"
# 提交
response = browser.submit_selected()
3-3 數據爬取
數據爬取的部分很簡單,語法與 BS4 類似,這裏就不展示說明了
search_results = browser.get_current_page().select('.news-list li .txt-box')
print('搜索結果爲:', len(search_results))
# 網頁數據爬取
for result in search_results:
# a標籤
element_a = result.select('a')[0]
# 獲取href值
# 注意:這裏的地址經過調轉纔是真實的文章地址
href = "https://mp.weixin.qq.com" + element_a.attrs['href']
text = element_a.text
print("標題:", text)
print("地址:", href)
# 關閉瀏覽器對象
browser.close()
3-4 反反爬
MechanicalSoup 除了設置 UA,還可以通過瀏覽器對象的「 session.proxies 」設置代理 IP
# 代理ip
proxies = {
'https': 'https_ip',
'http': 'http_ip'
}
# 設置代理ip
browser.session.proxies = proxies
4. 最後
文中結合微信文章搜索實例,使用 MechanicalSoup 完成了一次自動化及爬蟲操作
相比 Selenium,最大的區別是 Selenium 可以和 JS 進行交互;而 MechanicalSoup 不行
但是對於一些簡單的自動化場景,MechanicalSoup 是一種簡單、輕量級的解決方案
我已經將文中完整源碼文件傳到後臺,關注公衆號「 AirPython 」,後臺回覆「 ms 」即可獲得
如果你覺得文章還不錯,請大家 點贊、分享、留言 下,因爲這將是我持續輸出更多優質文章的最強動力!