一、概述
requests 作者開發,內建 pyppeteer。
最近爬蟲遇到的情況是,爬取的網站使用
JavaScript
渲染的,網站爬取的結果隻有一堆
JS
代碼。之前遇到這種情況的處理辦法是用
Splash
(一般是配合Scrapy),或者
Selenium
來爬取,介紹一下常用的模拟浏覽器執行,來爬去
js
渲染頁面的方法。
方法 | 介紹 |
Selenium | 驅動Chrome、Firefox等浏覽器爬取 |
Splinter | 依賴于Selenium、Flask |
Spynner | 依賴于PyQt |
pyppeteer | puppetter的Python版本 |
Splash | 常與Scrapy配合使用 |
requests-html | requests作者開發,內建pyppeteer |
安裝
pip3 install requests-html
二、基本使用
支援的特性
個人感覺最大的特點就是完整的JavaScrapt支援和異步支援。因為Requests不支援異步,之前使用異步請求的時候使用的是aiohttp(連結)和Python中的協程(連結)配合使用。
- 完整的JavaScript支援
- CSS Selectors 選擇
- XPath Selectors
- 模拟使用者代理
- 自動跟蹤連結重定向
- 連結池和cookie持久特性
- 異步支援
擷取頁面
非異步
之前解析庫都是專門的子產品支援,我們需要把網頁下載下傳下來,然後傳給HTMl解析庫,而Requests-html自帶這個功能,在爬取頁面十分友善。
from requests_html import HTMLSession
session = HTMLSession()
response = session.get('http://news.qq.com/')
print(response.html.html) # 擷取頁面内容
異步擷取
自帶異步請求方法
from requests_html import AsyncHTMLSession
asession = AsyncHTMLSession()
async def get_qq():
r = await asession.get('http://news.qq.com/')
return r
async def get_toutiao():
r = await asession.get('https://www.toutiao.com/')
return r
result = asession.run(get_qq, get_toutiao)
print(result)
擷取連結
links和absolute_links兩個屬性分别傳回HTML對象所包含的所有連結和絕對連結(均不包含錨點):
response.html.links()
response.html.absolute_links()
完整代碼:
from requests_html import HTMLSession
session = HTMLSession()
r = session.get('https://python.org/')
links = r.html.links
print("links",links)
absolute_links = r.html.absolute_links
print("absolute_links",absolute_links)
擷取元素
CSS選擇器
支援CSS和XPATH兩種文法來選取HTML元素。
def find(self, selector: str = "*", *, containing: _Containing = None, clean: bool = False, first: bool = False, _encoding: str = None)
- selector:要用的CSS選擇器
- clean:是否清理已發現的
和<script>
标簽的HTML。<style>
- contaning:傳回該屬性文本的标簽
- first:True 傳回第一個元素,否則傳回滿足條件的元素清單。
- _encoding:編碼格式
通路京東,搜尋x1關鍵字的商品清單
from requests_html import HTMLSession
session = HTMLSession()
r = session.get('https://search.jd.com/Search?keyword=x1&enc=utf-8&wq=x1&pvid=add52cb63f7e4887b5ba29406a5756ba')
link_list = r.html.find('.gl-item')
for i in link_list:
print(i.text)
View Code
執行輸出:
¥9999.00
聯想ThinkPad
X1
Carbon 2019(01CD)英特爾酷睿i5 14英寸輕薄筆記本電腦(i5-10210U 8G 512GSSD FHD)黑
...
Xpath選擇器
xpath(self, selector: str, *, clean: bool = False, first: bool = False, _encoding: str = None)
- selector:要用的XPATH選擇器
-
<script>
<style>
擷取新聞清單
from requests_html import HTMLSession
session = HTMLSession()
r = session.get('https://python.org/')
#裡面是css選擇器内容
text = r.html.xpath('//*[@class="menu"]/li/a/text()')
print(text)
JavaScript支援
就是在HTML結果上調用一下render函數,它會在使用者目錄(預設是~/.pyppeteer/)中下載下傳一個chromium,然後用它來執行JS代碼。
from requests_html import HTMLSession
session = HTMLSession()
response = session.get('https://www.zhihu.com/topic/19552832/hot')
response.html.render() # 不調用該方法無法擷取标題
print(response.html.xpath('//*[@id="root"]/div/main/div/div[1]/div[1]/div[1]/div/div/div/div[2]/h2/div'))
執行報錯:
pyppeteer.errors.PageError: Protocol Error: Connectoin Closed. Most likely the page has been closed.
解決辦法,參考連結:
https://github.com/miyakogi/pyppeteer/pull/160/files
需要修改源代碼
你的python安裝路徑\lib\site-packages\pyppeteer\connection.py
将
self._url, max_size=None, loop=self._loop)
修改為
self._url, max_size=None, loop=self._loop, ping_interval=None, ping_timeout=None)
再次執行,輸出:
[<Element 'div' class=('TopicMetaCard-title',)>]
render函數屬性
def render(self, retries: int = 8, script: str = None, wait: float = 0.2, scrolldown=False, sleep: int = 0, reload: bool = True, timeout: Union[float, int] = 8.0, keep_page: bool = False):
- retries:加載頁面失敗的次數
- script:頁面上需要執行的JS腳本
- wait:加載頁面的等待時間,防止逾時
- scrolldown:頁面向下滾動的次數
- sleep:在頁面渲染之後的等待時間
- reload:Flase頁面不會從浏覽器中加載,而是從記憶體中加載
- keep_page:True 允許你用r.html.page通路頁面
爬取知乎頁面,并且模拟下滑頁面。
from requests_html import HTMLSession
session = HTMLSession()
response = session.get('https://www.zhihu.com/topic/19552832/hot')
response.html.render(scrolldown=4,sleep=5)
for name in response.html.xpath("//h2[@class='ContentItem-title']/a/text()"):
print(name)
輸出:
如何看待Python和Java?到底入門學習哪一個更好?(附學習教程)
如何看待AI技術?什麼是AI?(附教程)
Python打包exe的王炸-Nuitka
...
本文參考連結:
https://blog.csdn.net/qq_1290259791/article/details/83413912
https://blog.csdn.net/weixin_39198406/article/details/86719814
https://www.jianshu.com/p/bd828b9cf74d