目錄
一 介紹
Python上有一個非常著名的HTTP庫——requests,相信大家都聽說過,用過的人都說非常爽!現在requests庫的作者又發布了一個新庫,叫做requests-html,看名字也能猜出來,這是一個解析HTML的庫,具備requests的功能以外,還新增了一些更加強大的功能,用起來比requests更爽!接下來我們來介紹一下它吧。
# 官網解釋 ''' This library intends to make parsing HTML (e.g. scraping the web) as simple and intuitive as possible. If you’re interested in financially supporting Kenneth Reitz open source, consider visiting this link. Your support helps tremendously with sustainability of motivation, as Open Source is no longer part of my day job. When using this library you automatically get: - Full JavaScript support! - CSS Selectors (a.k.a jQuery-style, thanks to PyQuery). - XPath Selectors, for the faint at heart. - Mocked user-agent (like a real web browser). - Automatic following of redirects. - Connection–pooling and cookie persistence. - The Requests experience you know and love, with magical parsing abilities. - Async Support '''
官網告訴我們,它比原來的requests模塊更加強大,並且為我們提供了一些新的功能!
- 支持JavaScript
- 支持CSS選擇器(又名jQuery風格, 感謝PyQuery)
- 支持Xpath選擇器
- 可自定義模擬User-Agent(模擬得更像真正的web瀏覽器)
- 自動追蹤重定向
- 連接池與cookie持久化
- 支持異步請求
二 安裝
安裝requests-html非常簡單,一行命令即可做到。需要注意一點就是,requests-html只支持Python 3.6或以上的版本,所以使用老版本的Python的同學需要更新一下Python版本了。
# pip3 install requests-html
三 如何使用requests-html?
在我們學爬蟲程序的時候用得最多的請求庫就是requests與urllib,但問題是這些包只給我們提供了如何去目標站點發送請求,然后獲取響應數據,接着再利用bs4或xpath解析庫才能提取我們需要的數據。

import requests from bs4 import BeautifulSoup url = 'http://www.zuihaodaxue.cn/' HEADERS = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36' } response = requests.get(url, headers=HEADERS) response.encoding = 'gbk' # print(response.status_code) # print(response.text) soup = BeautifulSoup(response.text, 'lxml') # 獲取最新的五則新聞 post_rankings = soup.find_all(name='article', attrs={"class": "post_ranking"}) # 循環打印新聞簡介內容 for post_ranking in post_rankings: new = post_ranking.find(name='div', attrs={"class": 'post_summary'}) print(new.text)
而在requests-html里面只需要一步就可以完成而且可以直接進行js渲染!requests的作者Kenneth Reitz 開發的requests-html 爬蟲包 是基於現有的框架 PyQuery、Requests、lxml、beautifulsoup4等庫進行了二次封裝,作者將Requests的簡單,便捷,強大又做了一次升級。
1、基本使用
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)
2、獲取鏈接(links與abolute_links)
links返回的結果 absolute_links返回的結果
from requests_html import HTMLSession # 獲取請求對象 session = HTMLSession() # 往京東主頁發送get請求 jd = session.get('https://jd.com/') # 得到京東主頁所有的鏈接,返回的是一個set集合 print(jd.html.links) print('*' * 1000) # 若獲取的鏈接中有相對路徑,我們還可以通過absolute_links獲取所有絕對鏈接 print(jd.html.absolute_links)
3、CSS選擇器與XPATH
request-html支持CSS選擇器和XPATH兩種語法來選取HTML元素。首先先來看看CSS選擇器語法,它需要使用HTML的 find 函數來查找元素。
''' CSS選擇器 and XPATH 1.通過css選擇器選取一個Element對象 2.獲取一個Element對象內的文本內容 3.獲取一個Element對象的所有attributes 4.渲染出一個Element對象的HTML內容 5.獲取Element對象內的特定子Element對象,返回列表 6.在獲取的頁面中通過search查找文本 7.支持XPath 8.獲取到只包含某些文本的Element對象 '''

from requests_html import HTMLSession session = HTMLSession() url = "https://www.qiushibaike.com/text/" # 獲取響應數據對象 obj = session.get(url) # 1.通過css選擇器選取一個Element對象 # 獲取id為content-left的div標簽,並且返回一個對象 content = obj.html.find('div#content-left', first=True) # 2.獲取一個Element對象內的文本內容 # 獲取content內所有文本 print(content.text) # 3.獲取一個Element對象的所有attributes # 獲取content內所有屬性 print(content.attrs) # 4.渲染出一個Element對象的完整的HTML內容 html = content.html print(html) # 5.獲取Element對象內的指定的所有子Element對象,返回列表 a_s = content.find('a') print(a_s) print(len(a_s)) # 79 # 循環所有的a標簽 for a in a_s: # 獲取a標簽內所有屬性的href屬性 並拼接 href = a.attrs['href'] if href.startswith('/'): url = 'https://www.qiushibaike.com' + href print(url) # 6.在獲取的頁面中通過search查找文本 # {}大括號相當於正則的從頭到后開始匹配,獲取當中想要獲取的數據 text = obj.html.search('把{}夾')[0] # 獲取從 "把" 到 "夾" 字的所有內容 text = obj.html.search('把糗事{}夾')[0] # 獲取從把子到夾字的所有內容 print(text) print('*' * 1000) # 7.支持XPath a_s = obj.html.xpath('//a') # 獲取html內所有的a標簽 for a in a_s: href = a.attrs['href'] # 若是//開頭的url都扔掉 if href.startswith('//'): continue # 若是/開頭的都是相對路徑 elif href.startswith('/'): print('https://www.qiushibaike.com' + href) # 8.獲取到只包含某些文本的Element對象(containing) # 獲取所有文本內容為幽默笑話大全_爆笑笑話_笑破你的肚子的搞笑段子 - 糗事百科 title標簽 # 注意: 文本內有空格也必須把空格帶上 title = obj.html.find('title', containing='幽默笑話大全_爆笑笑話_笑破你的肚子的搞笑段子 - 糗事百科') print(title)
四 支持JavaScript
支持JavaScript是我覺得作者更新后最為牛逼的一個地方,但是需要在第一次執行render的時候下載chromeium,然后通過它來執行js代碼。
1、render的使用
from requests_html import HTMLSession session = HTMLSession() url = 'http://www.win4000.com/' obj = session.get(url) obj.encoding = 'utf-8' obj.html.render()
注意:第一次運行render()方法時,它會將Chromium下載到您的主目錄中(例如~/.pyppeteer/)。這種情況只發生一次。
2、 下載Chromeium問題
因為是從國外的站點下載幾分鍾才3%,實在是太慢了。所以我們需要通過國內的鏡像去下載!需要做以下幾步:
-
- 手動下載Chrome
先去國內源下載自己需要的版本,地址:https://npm.taobao.org/mirrors/chromium-browser-snapshots/ - 修改chromeium_downloader.py文件
下載后之后解壓后,進入python安裝目錄下的\Lib\site-packages\pyppeteer目錄, 並打開chromium_downloader.py文件。
# 找到自己的操作系統相應的配置位置 ''' chromiumExecutable = { 'linux': DOWNLOADS_FOLDER / REVISION / 'chrome-linux' / 'chrome', 'mac': (DOWNLOADS_FOLDER / REVISION / 'chrome-mac' / 'Chromium.app' / 'Contents' / 'MacOS' / 'Chromium'), 'win32': DOWNLOADS_FOLDER / REVISION / 'chrome-win32' / 'chrome.exe', 'win64': DOWNLOADS_FOLDER / REVISION / 'chrome-win32' / 'chrome.exe', } ''' from pyppeteer import __chromium_revision__, __pyppeteer_home__ DOWNLOADS_FOLDER = Path(__pyppeteer_home__) / 'local-chromium' REVISION = os.environ.get('PYPPETEER_CHROMIUM_REVISION', __chromium_revision__) # 打印這兩個變量可以知道執行的驅動具體位置 print(DOWNLOADS_FOLDER) print(REVISION) ''' 由上面可以知道:chromium路徑是:C:\Users\Ray\AppData\Local\pyppeteer\pyppeteer\local-chromium\575458\chrome-win32\chrome.exe 所以自己建文件夾,然后一直到chrome-win32文件夾,把上面下載的chromium文件,拷貝到此目錄下 '''
- 手動下載Chrome
五 自定義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))
# 如果你有需要可以在header中修改其他參數。
六 模擬表單提交(POST)
HTMLSession封裝了
一整套的HTTP方法,包括get、post、delete等, 對應HTTP中各個方法。
# 表單登錄 r = session.post('http://httpbin.org/post', data={'username': 'tank_jam', 'password': 'tank9527'}) pprint(json.loads(r.html.html)) ''' # 打印結果 {'args': {}, 'data': '', 'files': {}, 'form': {'password': 'tank9527', 'username': 'tank_jam'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '35', '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'}, 'json': None, 'origin': '112.65.61.109, 112.65.61.109', 'url': 'https://httpbin.org/post'} '''
七 支持異步請求
requests-html內部就封裝好了aynsc異步請求的功能,可以提高我們的爬蟲效率。
from requests_html import AsyncHTMLSession from requests_html import HTMLSession import time # 使用異步發送請求 async_session = AsyncHTMLSession() async def get_baidu(): url = 'https://www.baidu.com/' res = await async_session.get(url) print(res.html.absolute_links) async def get_sougou(): url = 'https://www.sogou.com/' res = await async_session.get(url) print(res.html.links) start_time = time.time() async_session.run(get_baidu, get_sougou) print('耗時:', time.time() - start_time) # 同步發送請求 session = HTMLSession() start_time = time.time() res = session.get('https://www.baidu.com/') print(res.html.links) res = session.get('https://www.sogou.com/') print(res.html.absolute_links) print('耗時:', time.time() - start_time)