request-html


全面支持解析JavaScript!
CSS 選擇器 (jQuery風格, 感謝PyQuery).
XPath 選擇器, for the faint at heart.
自定義user-agent (就像一個真正的web瀏覽器).
自動追蹤重定向.
連接池與cookie持久化.
令人欣喜的請求體驗,魔法般的解析頁面.

接觸過爬蟲用的最多的包無非就是requests, urllib包,我們在使用這些包的時候顯示,用requests包去獲取響應,然后再利用pyquery或者bs4,xpath再去整理提取我們需要是目標數據。也就是下面兩步

import requests
from pyquery import PyQuery as pq

#獲取網頁
html = requests.get()
#解析網頁
doc = pq(html)

但是在 request-html 里只需要一步就可以完成,而且可以直接進行 js 渲染

requests的作者Kenneth Reitz 開發的requests-html 爬蟲包 是基於現有的框架 PyQuery、Requests、lxml、beautifulsoup4等庫進行了二次封裝,作者將Requests的簡單,便捷,強大又做了一次升級。這里是github地址

安裝:

pip install request-html

基本使用

from requests_html import HTMLSession

# 獲取請求對象
session = HTMLSession()
# 往新浪新聞主頁發送 get 請求
sina = session.get('https://news.sina.com.cn')
# print(sina.status_code)
sina.encoding = 'utf-8'

# 獲取響應文本信息,與requests無區別
print(sina.text)

獲取鏈接( links 與 absolute_links )

from requests_html import HTMLSession

# 獲取請求對象
session = HTMLSession()
jd = session.get('https://jd.com')
print(jd.html.links)

# 若獲取的鏈接中有相對路徑
# 我們還可以通過 absolute_links 獲取所有的絕對鏈接
print(jd.html.absolute_links)

CSS 選擇器與 XPATH

requests-html 支持 CSS 選擇器和 XPATH 兩種語法選取 HTML 元素

首先先來看看CSS選擇器語法,它需要使用HTML的 find 函數來查找元素。

from requests_html import HTMLSession

session = HTMLSession()
url = 'https://www.qiushibaike.com/text'

通過 CSS 選擇器選取一個 Element 對象

css選擇器語法:http://www.w3school.com.cn/cssref/css_selectors.asp

CSS選擇器示例:

  • a
  • a.someClass
  • a#someID
  • a[target=_blank]
# 獲取響應數據對象
obj = session.get(url)

# 通過 CSS 選擇器選取一個 Element 對象
# 獲取 id 為 content-left 的 div 標簽,標簽返回一個對象
content = obj.html.find('div#content-left', first=True)

獲取一個Element對象內的文本內容

content_text = content.text

獲取一個 Element 對象的完整的 HTML 內容

content_html = content.html

獲取一個Element對象的所有attributes

content_attrs = content.attrs

獲取Element對象內的指定的所有子Element對象,返回列表

a_list = content.find('a')

循環所有的 a 標簽

a_list = content.find('a')
for a in a_list:
 try:
     # 獲取a標簽內所有屬性的href屬性 並拼接
     href = a.attrs['href']
     if href.startswith('/'):
         url = 'https://www.qiushibaike.com' + href
         print(url)
 except:
     pass

在獲取的頁面中通過search查找文本

{}大括號相當於正則的從頭到后開始匹配,獲取當中想要獲取的數據

text = obj.html.search('把{}夾')[0]  # 獲取從 "把" 到 "夾" 字的所有內容
text = obj.html.search('把糗事{}夾')[0]  # 獲取從把子到夾字的所有內容
print(text)

支持 XPATH

xpath選擇器語法:http://www.w3school.com.cn/xpath/index.asp

a_list = obj.html.xpath('//a')  # 獲取 html 內所有的 a 標簽
for a in a_list:
 try:
     href = a.attrs['href']
     # 若是// 開頭的 url 都扔掉
     if href.startswith('//'):
         continue
     elif href.startswith('/'):
         print('https://www.qiushibaike.com' + href)
 except:
     pass

獲取到只包含某些文本的Element對象(containing)

# 獲取所有文本內容為幽默笑話大全_爆笑笑話_笑破你的肚子的搞笑段子 - 糗事百科 title標簽
# 注意: 文本內有空格也必須把空格帶上
title = obj.html.find('div', containing='后來')
print(title[0].text)

支持 JavaScript

下面就是重磅炸彈了!!!高能預警!!!

注意,當你第一次調用render()方法時,代碼將會自動下載Chromium,並保存在你的家目錄下(如:~/.pyppeteer/)。它只會下載這一次。

  • from requests_html import HTMLSession
    
    session = HTMLSession()
    res = session.get('https://piaofang.maoyan.com/dashboard')
    res.html.render()
    print(res.text)
    
  • render函數還有一些參數,介紹一下(這些參數有的還有默認值,直接看源代碼方法參數列表即可):

  • - retries: 加載頁面失敗的次數

  • - script: 頁面上需要執行的JS腳本(可選)

  • - wait: 加載頁面錢的等待時間(秒),防止超時(可選)

  • - scrolldown: 頁面向下滾動的次數

  • - sleep: 在頁面初次渲染之后的等待時間

  • - reload: 如果為假,那么頁面不會從瀏覽器中加載,而是從內存中加載

  • - keep_page: 如果為真,允許你用r.html.page訪問頁面

如果scrolldownsleep都指定,那么程序會在暫停相應時間后,再往后翻頁面(如:scrolldown=10, sleep=1

如果僅指定了sleep,程序會暫停相應時間,再返回數據

如果指定script,他將會在運行時執行提供的JavaScript。如:

script = """
    () => {
        return {
            width: document.documentElement.clientWidth,
            height: document.documentElement.clientHeight,
            deviceScaleFactor: window.devicePixelRatio,
        }
    }
"""

返回一段JavaScript的返回值:

>>> r.html.render(script=script)
{'width': 800, 'height': 600, 'deviceScaleFactor': 1}

自定義 User-Agent

有些網站會使用 User-Agent 來識別客戶端類型,有時候需要偽造UA來實現某些操作。

如果查看文檔的話會發現HTMLSession上的很多請求方法都有一個額外的參數**kwargs,這個參數用來向底層的請求傳遞額外參數。

我們先向網站發送一個請求,看看返回的網站信息。

from requests_html import HTMLSession
# pprint 可以把數據打印的更整齊
from pprint import pprint
import json
get_url = 'http://httpbin.org/get'

session = HTMLSession()
# 返回的是當前系統的 headers 信息
res = session.get(get_url)
pprint(json.loads(res.html.html))

# 可以在發送請求的時候更換 user-agent
ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0'
post_url = 'http://httpbin.org/get'
res = session.get(post_url, headers={'user-agent': ua})
pprint(json.loads(res.html.html))

request-html 更多方法


模擬表單提交(POST)

HTMLSession 封裝了一整套的HTTP方法,包括get、post、delete等, 對應HTTP中各個方法。

# 表單登錄
res = session.post('http://httpbin.org/post', data={'username': 'santa', 'password': '123'})
pprint(json.loads(res.html.html))
''' # 打印結果
{'args': {},
'data': '',
'files': {},
'form': {'password': '123', 'username': 'santa'},
'headers': {'Accept': '*/*',
          'Accept-Encoding': 'gzip, deflate',
          'Content-Length': '27',
          'Content-Type': 'application/x-www-form-urlencoded',
          'Host': 'httpbin.org',
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) '
                        'AppleWebKit/603.3.8 (KHTML, like Gecko) '
                        'Version/10.1.2 Safari/603.3.8',
          'X-Amzn-Trace-Id': 'Root=1-5e40d021-0261ed6c9fbc7df0daf90e98'},
'json': None,
'origin': '117.153.8.82',
'url': 'http://httpbin.org/post'}
'''

async異步使用

requests-html內部就封裝好了aynsc異步請求的功能,可以提高我們的爬蟲效率

# 使用異步發送請求
async_session = AsyncHTMLSession()
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
async def get_taobao():
 url = 'https://www.taobao.com/'
 res = await async_session.get(url, headers={'user-agent': ua})
 # print(res.html.links)
 return res.html.xpath("//head/title/text()")[0]

async def get_jd():
 url = 'https://www.jd.com/'
 res = await async_session.get(url)
 # print(res.html.absolute_links)
 return res.html.xpath("//head/title/text()")[0]

start_time = time.time()
res = async_session.run(get_taobao, get_jd)
print(res)
print(time.time()-start_time)

# 同步發送請求
session = HTMLSession()

start_time = time.time()
res = session.get('https://www.jd.com')
print(res.html.links)
res = session.get('https://www.taobao.com')
print(res.html.absolute_links)
print('fd ',time.time()-start_time)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM