小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

requests庫的作者又發(fā)布了一個新庫requests-htmlpython爬蟲 requests

 看見就非常 2020-05-13

一 介紹

  Python上有一個非常著名的HTTP庫——requests,相信大家都聽說過,用過的人都說非常爽!現(xiàn)在requests庫的作者又發(fā)布了一個新庫,叫做requests-html,看名字也能猜出來,這是一個解析HTML的庫,具備requests的功能以外,還新增了一些更加強大的功能,用起來比requests更爽!接下來我們來介紹一下它吧。

復(fù)制代碼
復(fù)制代碼
# 官網(wǎng)解釋'''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
    '''

復(fù)制代碼
復(fù)制代碼

  官網(wǎng)告訴我們,它比原來的requests模塊更加強大,并且為我們提供了一些新的功能!

  • 支持JavaScript

  • 支持CSS選擇器(又名jQuery風(fēng)格, 感謝PyQuery)

  • 支持Xpath選擇器

  • 可自定義模擬User-Agent(模擬得更像真正的web瀏覽器)

  • 自動追蹤重定向

  • 連接池與cookie持久化

  • 支持異步請求

二 安裝

  安裝requests-html非常簡單,一行命令即可做到。需要注意一點就是,requests-html只支持Python 3.6或以上的版本,所以使用老版本的Python的同學(xué)需要更新一下Python版本了。

# pip3 install requests-html

三 如何使用requests-html?

  在我們學(xué)爬蟲程序的時候用得最多的請求庫就是requests與urllib,但問題是這些包只給我們提供了如何去目標(biāo)站點發(fā)送請求,然后獲取響應(yīng)數(shù)據(jù),接著再利用bs4或xpath解析庫才能提取我們需要的數(shù)據(jù)。

以往爬蟲的請求與解析

  而在requests-html里面只需要一步就可以完成而且可以直接進行js渲染!requests的作者Kenneth Reitz 開發(fā)的requests-html 爬蟲包 是基于現(xiàn)有的框架 PyQuery、Requests、lxml、beautifulsoup4等庫進行了二次封裝,作者將Requests的簡單,便捷,強大又做了一次升級。

  requests-html和其他解析HTML庫最大的不同點在于HTML解析庫一般都是專用的,所以我們需要用另一個HTTP庫先把網(wǎng)頁下載下來,然后傳給那些HTML解析庫。而requests-html自帶了這個功能,所以在爬取網(wǎng)頁等方面非常方便。

 

  1、基本使用

復(fù)制代碼
復(fù)制代碼
from requests_html import HTMLSession

# 獲取請求對象
session = HTMLSession()

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

# 獲取響應(yīng)文本信息,與requests無區(qū)別

print(sina.text)

復(fù)制代碼
復(fù)制代碼

  2、獲取鏈接(links與abolute_links)

    links返回的結(jié)果                                  absolute_links返回的結(jié)果

             

復(fù)制代碼
復(fù)制代碼
from requests_html import HTMLSession

# 獲取請求對象
session = HTMLSession()

# 往京東主頁發(fā)送get請求
jd = session.get('https://jd.com/')

# 得到京東主頁所有的鏈接,返回的是一個set集合
print(jd.html.links)
print('*' * 1000)

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

復(fù)制代碼
復(fù)制代碼

  3、CSS選擇器與XPATH

  request-html支持CSS選擇器和XPATH兩種語法來選取HTML元素。首先先來看看CSS選擇器語法,它需要使用HTML的 find 函數(shù)來查找元素。

復(fù)制代碼
復(fù)制代碼
'''  CSS選擇器 and XPATH
      1.通過css選擇器選取一個Element對象
      2.獲取一個Element對象內(nèi)的文本內(nèi)容
      3.獲取一個Element對象的所有attributes
      4.渲染出一個Element對象的HTML內(nèi)容
      5.獲取Element對象內(nèi)的特定子Element對象,返回列表
      6.在獲取的頁面中通過search查找文本
      7.支持XPath
      8.獲取到只包含某些文本的Element對象'''
復(fù)制代碼
復(fù)制代碼
view code

四 支持JavaScript

  支持JavaScript是我覺得作者更新后最為牛逼的一個地方,但是需要在第一次執(zhí)行render的時候下載chromeium,然后通過它來執(zhí)行js代碼。

1、render的使用

復(fù)制代碼
復(fù)制代碼
from requests_html import HTMLSession

session = HTMLSession()

url = 'http://www./'

obj = session.get(url)

obj.encoding = 'utf-8'

obj.html.render()

復(fù)制代碼
復(fù)制代碼

  注意:第一次運行render()方法時,它會將Chromium下載到您的主目錄中(例如~/.pyppeteer/)。這種情況只發(fā)生一次。

2、 下載Chromeium問題

  因為是從國外的站點下載幾分鐘才3%,實在是太慢了。所以我們需要通過國內(nèi)的鏡像去下載!需要做以下幾步:

    • 手動下載Chrome

      先去國內(nèi)源下載自己需要的版本,地址:https://npm./mirrors/chromium-browser-snapshots/

    • 修改chromeium_downloader.py文件
      下載后之后解壓后,進入python安裝目錄下的\Lib\site-packages\pyppeteer目錄, 并打開chromium_downloader.py文件。

      View Code 

五 自定義User-Agent

  有些網(wǎng)站會使用User-Agent來識別客戶端類型,有時候需要偽造UA來實現(xiàn)某些操作。如果查看文檔的話會發(fā)現(xiàn)HTMLSession上的很多請求方法都有一個額外的參數(shù)**kwargs,這個參數(shù)用來向底層的請求傳遞額外參數(shù)。我們先向網(wǎng)站發(fā)送一個請求,看看返回的網(wǎng)站信息。

復(fù)制代碼
復(fù)制代碼
from requests_html import HTMLSession# pprint可以把數(shù)據(jù)打印得更整齊from pprint import pprintimport json
get_url = 'http:///get'

session = HTMLSession()

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

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

# 如果你有需要可以在header中修改其他參數(shù)。

復(fù)制代碼
復(fù)制代碼

六 模擬表單提交(POST)

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

復(fù)制代碼
復(fù)制代碼
# 表單登錄r = session.post('http:///post', data={'username': 'tank_jam', 'password': 'tank9527'})
pprint(json.loads(r.html.html))''' # 打印結(jié)果{'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': '',
             '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:///post'}'''
復(fù)制代碼
復(fù)制代碼

七 支持異步請求

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

復(fù)制代碼
復(fù)制代碼
from requests_html import AsyncHTMLSessionfrom requests_html import HTMLSessionimport time

# 使用異步發(fā)送請求
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)

# 同步發(fā)送請求
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)

復(fù)制代碼
復(fù)制代碼

1. 開始

Python 中可以進行網(wǎng)頁解析的庫有很多,常見的有 BeautifulSoup 和 lxml 等。在網(wǎng)上玩爬蟲的文章通常都是介紹 BeautifulSoup 這個庫,我平常也是常用這個庫,最近用 Xpath 用得比較多,使用 BeautifulSoup 就不大習(xí)慣,很久之前就知道 Reitz 大神出了一個叫 Requests-HTML 的庫,一直沒有興趣看,這回可算歹著機會用一下了。

使用 pip install requests-html安裝,上手和 Reitz 的其他庫一樣,輕松簡單:

 from requests_html import HTMLSession
 session = HTMLSession()
 
 r = session.get('https://www./jobs/')

這個庫是在 requests 庫上實現(xiàn)的,r 得到的結(jié)果是 Response 對象下面的一個子類,多個一個 html 的屬性。所以 requests 庫的響應(yīng)對象可以進行什么操作,這個 r 也都可以。如果需要解析網(wǎng)頁,直接獲取響應(yīng)對象的 html 屬性:

 r.html

2. 原理

不得不膜拜 Reitz 大神太會組裝技術(shù)了。實際上 HTMLSession 是繼承自 requests.Session 這個核心類,然后將 requests.Session 類里的 requests 方法改寫,返回自己的一個 HTMLResponse 對象,這個類又是繼承自 requests.Response,只是多加了一個 _from_response 的方法來構(gòu)造實例:

 class HTMLSession(requests.Session):
     # 重寫 request 方法,返回 HTMLResponse 構(gòu)造
     def request(self, *args, **kwargs) -> HTMLResponse:
         r = super(HTMLSession, self).request(*args, **kwargs)
         return HTMLResponse._from_response(r, self)
 class HTMLResponse(requests.Response):
  # 構(gòu)造器
     @classmethod
     def _from_response(cls, response, session: Union['HTMLSession', 'AsyncHTMLSession']):
         html_r = cls(session=session)
         html_r.__dict__.update(response.__dict__)
         return html_r

之后在 HTMLResponse 里定義屬性方法 html,就可以通過 html 屬性訪問了,實現(xiàn)也就是組裝 PyQuery 來干。核心的解析類也大多是使用 PyQuery 和 lxml 來做解析,簡化了名稱,挺討巧的。

3. 元素定位

元素定位可以選擇兩種方式:

css 選擇器

  • css選擇器

  • xpath

 # css 獲取有多少個職位
 jobs = r.html.find("h1.call-to-action")
 # xpath 獲取
 jobs = r.html.xpath("//h1[@class='call-to-action']")

方法名非常簡單,符合 Python 優(yōu)雅的風(fēng)格,這里不妨對這兩種方式簡單的說明:

4. CSS 簡單規(guī)則

  • 標(biāo)簽名 h1

  • id 使用 #id 表示

  • class 使用 .class_name 表示

  • 謂語表示:h1[prop=value]

5. Xpath簡單規(guī)則

  • 路徑 // 或者 /

  • 標(biāo)簽名

  • 謂語 [@prop=value]

  • 軸定位 名稱::元素名[謂語]

定位到元素以后勢必要獲取元素里面的內(nèi)容和屬性相關(guān)數(shù)據(jù),獲取文本:

 jobs.text
 jobs.full_text

獲取元素的屬性:

 attrs = jobs.attrs
 value = attrs.get("key")

還可以通過模式來匹配對應(yīng)的內(nèi)容:

 ## 找某些內(nèi)容匹配
 r.html.search("Python {}")
 r.html.search_all()

這個功能看起來比較雞肋,可以深入研究優(yōu)化一下,說不定能在 github 上混個提交。

6. 人性化操作

除了一些基礎(chǔ)操作,這個庫還提供了一些人性化的操作。比如一鍵獲取網(wǎng)頁的所有超鏈接,這對于整站爬蟲應(yīng)該是個福音,URL 管理比較方便:

 r.html.absolute_links
 r.html.links
 

內(nèi)容頁面通常都是分頁的,一次抓取不了太多,這個庫可以獲取分頁信息:

 print(r.html)
 # 比較一下
 for url in r.html:
     print(url)
 

結(jié)果如下:

 # print(r.html)
 <HTML url='https://www./jobs/'>
 # for
 <HTML url='https://www./jobs/'>
 <HTML url='https://www./jobs/?page=2'>
 <HTML url='https://www./jobs/?page=3'>
 <HTML url='https://www./jobs/?page=4'>
 <HTML url='https://www./jobs/?page=5'>
 

通過迭代器實現(xiàn)了智能發(fā)現(xiàn)分頁,這個迭代器里面會用一個叫 _next 的方法,貼一段源碼感受下:

 def get_next():
  candidates = self.find('a', containing=next_symbol)
 
  for candidate in candidates:
  if candidate.attrs.get('href'):
  # Support 'next' rel (e.g. reddit).
  if 'next' in candidate.attrs.get('rel', []):
  return candidate.attrs['href']
 

通過查找 a 標(biāo)簽里面是否含有指定的文本來判斷是不是有下一頁,通常我們的下一頁都會通過 下一頁 或者 加載更多 來引導(dǎo),他就是利用這個標(biāo)志來進行判斷。默認(rèn)的以列表形式存在全局:['next', 'more', 'older']。我個人認(rèn)為這種方式非常不靈活,幾乎沒有擴展性。感興趣的可以往 github 上提交代碼優(yōu)化。

7. 加載 js

也許是考慮到了現(xiàn)在 js 的一些異步加載,這個庫支持 js 運行時,官方說明如下:

Reloads the response in Chromium, and replaces HTML contentwith an updated version, with JavaScript executed.

使用非常簡單,直接調(diào)用以下方法:

 r.html.render()
 

第一次使用的時候會下載 Chromium,不過國內(nèi)你懂的,自己想辦法去下吧,就不要等它自己下載了。render 函數(shù)可以使用 js 腳本來操作頁面,滾動操作單獨做了參數(shù)。這對于上拉加載等新式頁面是非常友好的。

8. 總結(jié)

Reitz 大神設(shè)計出來的東西還是一如既往的簡單好用,自己不多做,大多用別人的東西組裝,簡化 api。真是夠人性。不過有的地方還是優(yōu)化空間,希望有興趣和精力的童鞋去 github 上關(guān)注一下這個項目。


昨天寫了requests庫好!最近requests庫的作者又發(fā)布了一個新庫,叫做requests-html,看名字也能猜出來,這是一個解析HTML的庫,而且用起來和requests一樣爽,下面就來介紹一下它。

一、安裝

pip install requests-html

二、基本使用

獲取網(wǎng)頁

復(fù)制代碼
復(fù)制代碼
from requests_html import HTMLSession

session = HTMLSession()
r = session.get('https://www./text/')
// 查看頁面內(nèi)容
print(r.html.html)

復(fù)制代碼
復(fù)制代碼

獲取鏈接

linksabsolute_links兩個屬性分別返回HTML對象所包含的所有鏈接和絕對鏈接(均不包含錨點)。

# 獲取鏈接print(r.html.links)print(r.html.absolute_links)

結(jié)果如下

{'/article/104353012', '/article/120616112', '/users/32331196/'}
{'https://www./imgrank/', 'https://www./article/120669516', 'https://www./article/120682041'}

獲取元素

request-html支持CSS選擇器和XPATH兩種語法來選取HTML元素。首先先來看看CSS選擇器語法,它需要使用HTML的find函數(shù),該函數(shù)有5個參數(shù),作用如下:

  • selector,要用的CSS選擇器;

  • clean,布爾值,如果為真會忽略HTML中style和script標(biāo)簽造成的影響(原文是sanitize,大概這么理解);

  • containing,如果設(shè)置該屬性,會返回包含該屬性文本的標(biāo)簽;

  • first,布爾值,如果為真會返回第一個元素,否則會返回滿足條件的元素列表;

  • _encoding,編碼格式。

例子:

復(fù)制代碼
復(fù)制代碼
# 首頁菜單文本print(r.html.find('div#menu', first=True).text)# 首頁菜單元素print(r.html.find('div#menu a'))# 段子內(nèi)容print(list(map(lambda x: x.text, r.html.find('div.content span'))))
復(fù)制代碼
復(fù)制代碼

結(jié)果如下,

復(fù)制代碼
復(fù)制代碼
熱門 24小時 熱圖 文字 穿越 糗圖 新鮮
[<Element 'a' href='/' rel=('nofollow',)>, <Element 'a' href='/hot/'>, <Element 'a' href='/imgrank/'>, <Element 'a' id='highlight' href='/text/'>, <Element 'a' href='/history/'>, <Element 'a' href='/pic/'>, <Element 'a' href='/textnew/'>]
['有一次,幾位大城市的朋友來家里玩,我招待他們吃風(fēng)干羊肉做臊子的饸饹面,這是我們老家最具特色的美食!飯快熟的時候,老婆讓我在園子里摘點“芫荽 ”,朋友問我,“芫荽”是什么東東?我給他們翻譯解釋說:我們本地土話叫“芫荽”,你們城里人講普通話叫香菜,他們還大笑了一場。\n前天下雨沒事兒干,翻看新華字典,突然發(fā)現(xiàn)“芫荽”才是香菜的學(xué)名,Tm香菜才是土話!而且我們地方方言就這兩個字發(fā)音還特別標(biāo)準(zhǔn)!', '昨天晚上跟老婆吵架,他抓起我的手機就摔了。我立馬摔了他的,結(jié)果我的還能用,他的壞了。高潮是人家立刻出門買了個新的!我艸,是不是中計了??', '小姨要去高鐵站,我看著大大小小的箱子說:坐公交車要轉(zhuǎn)車,轉(zhuǎn)來轉(zhuǎn)去要一個多小時,太不方便了,不如我開車送你吧。\n小姨遲疑了一下,同意了。\n我準(zhǔn)時把小姨送到了高鐵站,正好趕上檢票。\n小姨高興地說:自己開車就是方便,不過幸好你媽聰明,讓我們提前兩個多小時就出發(fā)了!'
復(fù)制代碼
復(fù)制代碼

XPAT語法,需要另一個函數(shù)xpath的支持,它有4個參數(shù):

  • selector,要用的XPATH選擇器;

  • clean,布爾值,如果為真會忽略HTML中style和script標(biāo)簽造成的影響(原文是sanitize,大概這么理解);

  • first,布爾值,如果為真會返回第一個元素,否則會返回滿足條件的元素列表;

  • _encoding,編碼格式。

還是上面的例子,不過這次使用XPATH語法:

print(r.html.xpath("//div[@id='menu']", first=True).text)print(r.html.xpath("//div[@id='menu']/a"))print(r.html.xpath("//div[@class='content']/span/text()"))

輸出和上面那個幾乎一樣,之所以說是“幾乎”,因為第三個輸出會多出幾個換行符,不知道什么原因。需要注意的一點是如果XPATH中包含text()@href這樣的子屬性,那么結(jié)果相應(yīng)的會變成簡單的字符串類型,而不是HTML元素。

['\n\n\n我一份文件忘家里了,又懶得回家取,就給小姨子發(fā)短信息: 幫我把文件送來,晚上我謝謝你。等半天也沒送來文件,我只好打個車回家自己拿,到家一進屋,我就發(fā)現(xiàn)氣氛不對勁,老婆鐵青著臉,兩手掐著腰,小姨子站旁邊對我怒目而視。']

元素內(nèi)容

糗事百科首頁LOGO的HTML代碼如下所示:

<div class="logo" id="hd_logo">
<a href="/"><h1>糗事百科</h1></a>
</div>

我們來選取這個元素:

e = r.html.find("div#hd_logo", first=True)

要獲取元素的文本內(nèi)容,用text屬性:

print(e.text)# 糗事百科

要獲取元素的attribute,用attr屬性:

print(e.attrs)# {'class': ('logo',), 'id': 'hd_logo'}

要獲取元素的HTML代碼,用html屬性:

print(e.html)# <div class="logo" id="hd_logo"># <a href="/"><h1>糗事百科</h1></a># </div>

要搜索元素的文本內(nèi)容,用search函數(shù),比如說我們現(xiàn)在想知道是糗事什么科:

print(e.search("糗事{}科")[0])#

最后還有前面提到的兩個鏈接屬性:

print(e.absolute_links)print(e.links)# {'https://www./'}# {'/'}
print(e.absolute_links)print(e.links)# {'https://www./'}# {'/'}

三、進階用法

JavaScript支持

有些網(wǎng)站是使用JavaScript渲染的,這樣的網(wǎng)站爬取到的結(jié)果只有一堆JS代碼,這樣的網(wǎng)站requests-html也可以處理,關(guān)鍵一步就是在HTML結(jié)果上調(diào)用一下render函數(shù),它會在用戶目錄(默認(rèn)是~/.pyppeteer/)中下載一個chromium,然后用它來執(zhí)行JS代碼。下載過程只在第一次執(zhí)行,以后就可以直接使用chromium來執(zhí)行了。

render函數(shù)還有一些參數(shù),順便介紹一下(這些參數(shù)有的還有默認(rèn)值,直接看源代碼方法參數(shù)列表即可):

  • retries: 加載頁面失敗的次數(shù)

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

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

  • scrolldown: 頁面向下滾動的次數(shù)

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

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

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

比如說簡書的用戶頁面上用戶的文章列表就是一個異步加載的例子,初始只顯示最近幾篇文章,如果想爬取所有文章,就需要使用scrolldown配合sleep參數(shù)模擬下滑頁面,促使JS代碼加載所有文章。

智能分頁

有些網(wǎng)站會分頁顯示內(nèi)容,例如reddit。

復(fù)制代碼
復(fù)制代碼
>>> r = session.get('https://')
>>> for html in r.html:
...     print(html)
<HTML url='https://www./'>
<HTML url='https://www./?count=25&after=t3_81puu5'>
<HTML url='https://www./?count=50&after=t3_81nevg'>
<HTML url='https://www./?count=75&after=t3_81lqtp'>
<HTML url='https://www./?count=100&after=t3_81k1c8'>
<HTML url='https://www./?count=125&after=t3_81p438'>
<HTML url='https://www./?count=150&after=t3_81nrcd'>
…
復(fù)制代碼
復(fù)制代碼

請求下一個網(wǎng)頁就很容易了

>>> r = session.get('https://')
>>> r.html.next()'https://www./?count=25&after=t3_81pm82'

直接使用HTML

前面介紹的都是通過網(wǎng)絡(luò)請求HTML內(nèi)容

復(fù)制代碼
復(fù)制代碼
>>> from requests_html import HTML
>>> doc = """<a href='https://'>"""

>>> html = HTML(html=doc)
>>> html.links
{'https://'}

復(fù)制代碼
復(fù)制代碼

直接渲染JS代碼也可以:

復(fù)制代碼
復(fù)制代碼
# 和上面一段代碼接起來>>> script = """
        () => {
            return {
                width: document.documentElement.clientWidth,
                height: document.documentElement.clientHeight,
                deviceScaleFactor: window.devicePixelRatio,
            }
        }    """>>> val = html.render(script=script, reload=False)

>>> print(val)
{'width': 800, 'height': 600, 'deviceScaleFactor': 1}

>>> print(html.html)
<html><head></head><body><a href="https://"></a></body></html>

復(fù)制代碼
復(fù)制代碼

自定義請求

前面都是簡單的用GET方法獲取請求,如果需要登錄等比較復(fù)雜的過程,就不能用get方法了。HTMLSession類包含了豐富的方法,可以幫助我們完成需求。下面介紹一下這些方法。

自定義用戶代理

有些網(wǎng)站會使用UA來識別客戶端類型,有時候需要偽造UA來實現(xiàn)某些操作。如果查看文檔的話會發(fā)現(xiàn)HTMLSession上的很多請求方法都有一個額外的參數(shù)**kwargs,這個參數(shù)用來向底層的請求傳遞額外參數(shù)。我們先向網(wǎng)站發(fā)送一個請求,看看返回的網(wǎng)站信息。

from pprint import pprint
r = session.get('http:///get')
pprint(json.loads(r.html.html))

返回結(jié)果如下:

復(fù)制代碼
復(fù)制代碼
{'args': {}, 'headers': {'Accept': '*/*',             'Accept-Encoding': 'gzip, deflate',             'Connection': 'close',             'Host': '',             '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'}, 'origin': '110.18.237.233', 'url': 'http:///get'}
復(fù)制代碼
復(fù)制代碼

可以看到UA是requests-html自帶的UA,下面換一個UA:

ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0'r = session.get('http:///get', headers={'user-agent': ua})
pprint(json.loads(r.html.html))

可以看到UA確實發(fā)生了變化:

復(fù)制代碼
復(fù)制代碼
{'args': {}, 'headers': {'Accept': '*/*',             'Accept-Encoding': 'gzip, deflate',             'Connection': 'close',             'Host': '',             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) '
                           'Gecko/20100101 Firefox/62.0'}, 'origin': '110.18.237.233', 'url': 'http:///get'}
復(fù)制代碼
復(fù)制代碼

當(dāng)然這里僅僅是換了一個UA,如果你有需要可以在header中修改其他參數(shù)。

模擬表單登錄

HTMLSession帶了一整套的HTTP方法,包括get、post、delete等,對應(yīng)HTTP中各個方法。比如下面我們就來模擬一下表單登錄:

# 表單登錄r = session.post('http:///post', data={'username': 'yitian', 'passwd': 123456})
pprint(json.loads(r.html.html))

結(jié)果如下,可以看到forms中確實收到了提交的表單值:

復(fù)制代碼
復(fù)制代碼
{'args': {}, 'data': '', 'files': {}, 'form': {'passwd': '123456', 'username': 'yitian'}, 'headers': {'Accept': '*/*',             'Accept-Encoding': 'gzip, deflate',             'Connection': 'close',             'Content-Length': '29',             'Content-Type': 'application/x-www-form-urlencoded',             'Host': '',             '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': '110.18.237.233', 'url': 'http:///post'}
復(fù)制代碼
復(fù)制代碼

如果有上傳文件的需要,做法也是類似的。如果了解過requests庫的同學(xué)可能對這里的做法比較熟悉,沒有錯,這其實就是requests的用法。requests-html通過暴露**kwargs的方法,讓我們可以對請求進行定制,將額外參數(shù)直接傳遞給底層的requests方法。所以如果有什么疑問的話,直接去看requests文檔就好了。

前言

requests雖好,但有個遺憾,它無法加載JavaScript,當(dāng)訪問一個url地址的時候,不能像selenium一樣渲染整個html頁面出來。
requests-html終于可以支持JavaScript了,這就相當(dāng)于是一個真正意義上的無界面瀏覽器了。
中文文檔地址:https://cncert./requests-html-doc-cn/#/

JavaScript支持

當(dāng)?shù)谝淮问褂胷ender() 渲染頁面的時候,會自動下載chromium,但只會下載這一次,后面就不會下載了。

from requests_html import HTMLSession
session = HTMLSession()

r = session.get('https://www.cnblogs.com/yoyoketang/')
r.html.render() # 首次使用,自動下載chromium

render()渲染頁面

到底渲染html頁面是個什么概念呢?可以請求之后對比抓包看下,不使用render()之前,只發(fā)一個請求

使用render()之后,會發(fā)很多請求,類型于手工在瀏覽器上輸入url后,瀏覽器渲染整個完整的頁面,這正是我們想要的模擬瀏覽器發(fā)請求

案例

接下來訪問我的博客地址后,抓取我的個人信息

from requests_html import HTMLSession
session = HTMLSession()

r = session.get('https://www.cnblogs.com/yoyoketang/', verify=False)
r.html.render() # 首次使用,自動下載chromium
# print(r.html.html)
d = r.html.find("#profile_block", first=True)
print(d.text)

打印結(jié)果

昵稱:上海-悠悠
園齡:2年4個月
粉絲:1570
關(guān)注:73
+加關(guān)注

困擾很久的問題終于找到了解決辦法,更多強大的功能可以去requests-html的GitHub地址https://github.com/kennethreitz/requests-html

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多