天天看點

Reuqests-html教程

一、概述

Reuqests-html教程

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>

    <style>

    标簽的HTML。
  • contaning:傳回該屬性文本的标簽
  • first:True 傳回第一個元素,否則傳回滿足條件的元素清單。
  • _encoding:編碼格式

通路京東,搜尋x1關鍵字的商品清單

Reuqests-html教程
Reuqests-html教程
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

Reuqests-html教程

需要修改源代碼

你的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