整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          深入HTTP請求流程

          深入HTTP請求流程

          X0

          HTTP(HyperText Transfer Protocol)超文本傳輸協(xié)議,是web服務(wù)器到web瀏覽器之間傳輸?shù)耐ㄐ乓?guī)則。

          0x01

          HTTP協(xié)議目前最新版本是1.1,HTTP是一種無狀態(tài)的協(xié)議,只能由客戶端發(fā)起,服務(wù)器端不能主動向客戶端發(fā)送數(shù)據(jù)。

          應(yīng)答模型:

          Request請求

          客戶端=============》服務(wù)端

          《============

          Response響應(yīng)

          0x02 HTTP請求

          包括三個部分:1、請求行; 2、請求頭; 3、請求正文。

          實(shí)例:

          GET /notification/notification_count/ HTTP/1.1 請求行

          Host: mp.xxxxxx.com 請求頭

          User-Agent: Mozilla/5.0 (X11; Linux i686; rv:52.0) Gecko/20100101 Firefox/52.0 (User-Agent代表瀏覽器標(biāo)識。)

          Accept: application/json, text/javascript, */*; q=0.01 正文

          Accept-Language: en-US,en;q=0.5

          Accept-Encoding: gzip, deflate

          Referer: http://mp.toutiao.com/profile_v2/publish

          X-Requested-With: XMLHttpRequest

          圖例brupsuite:

          使用python socket測試http響應(yīng)的效果:

          import socket

          t_host="www.toutiao.com"

          t_port=80

          client=socket.socket()

          client.connect((t_host,t_port))

          client.send("GET / HTTP/1.1\r\nHost:toutiao.com\r\n\r\n")

          response=client.recv(4096)

          print response

          HTTP/1.1 502 Bad Gateway //響應(yīng)行 HTTP的版, 狀態(tài)碼 502,消息是Bad Gateway

          Server: Tengine //響應(yīng)頭 由服務(wù)器向客戶端發(fā)送

          Content-Length: 0

          Connection: keep-alive

          Via: cache5.cn218[0,502-257,M], cache4.cn218[14,1,502001]

          X-Swift-Error: dns domain not exist

          Timing-Allow-Origin: *

          EagleId: 790e0d0415057759521686693e

          ........由于response獲取的字節(jié)有限下面是響應(yīng)正文,是服務(wù)器向客戶端發(fā)送的HTML數(shù)據(jù)。

          EOF:下一遍我將講述HTTP的請求方法,請期待。

          碼如下:

          import requests
          from bs4 import BeautifulSoup
          import pandas as pd
          #下面是請求數(shù)據(jù)
          url="https://www.163.com/" #設(shè)置請求網(wǎng)址為搜索網(wǎng)址
          response=requests.get(url) #對163網(wǎng)站就行g(shù)et請求并將請求結(jié)果賦值給response
          response.encoding="GBK" #設(shè)置編碼為GBK格式的
          html=response.text #獲取網(wǎng)頁的html源代碼并賦值給html
          #下面是解析數(shù)據(jù)
          soup=BeautifulSoup(html)
          content=soup.findAll('div') #查找所有的div標(biāo)簽內(nèi)容并賦值給content
          print(content) #打印content
          

          代碼運(yùn)行結(jié)果如下圖所示:

          多朋友都聽說過Python的大名,而Python也擁有眾多的爬蟲框架,其中最簡單的莫過于requests-html了。它和著名的網(wǎng)絡(luò)請求庫requests是同一個作者,著重于XML數(shù)據(jù)提取,可以說是最簡單的爬蟲框架了。



          安裝requests-html

          安裝這個類庫非常簡單,直接通過pip就可以安裝了。

          pip install requests-html

          開始使用

          requests-html用起來也十分簡單,下面是一個簡單例子。照例說明一下,第一段引入了HTMLSession用于創(chuàng)建連接,獲取網(wǎng)頁數(shù)據(jù)。第二段創(chuàng)建連接,獲取了我的簡書用戶頁面。第三段用xpath語法獲取了網(wǎng)頁上的用戶名,最后打印出來。

          from requests_html import HTMLSession
          
          session=HTMLSession()
          response=session.get(
              'https://www.jianshu.com/u/7753478e1554')
          
          username=response.html.xpath(
              '//a[@class="name"]/text()', first=True)
          
          
          print(username)
          

          看起來是不是很簡單?沒錯,確實(shí)很簡單,接下來還有一些更加有趣的功能。

          分析網(wǎng)頁

          編寫爬蟲之前還要做一件事情,就是分析網(wǎng)頁的結(jié)構(gòu)。這個工作其實(shí)也很簡單,打開你要訪問的網(wǎng)頁,按F12打開開發(fā)人員工具,可以看到最左邊有這么一個按鈕。點(diǎn)擊這個按鈕,然后點(diǎn)擊網(wǎng)頁上你想要查看的網(wǎng)頁元素,然后你就可以發(fā)現(xiàn)這個元素對應(yīng)的相關(guān)源代碼已經(jīng)為你定位完畢了。

          定位按鈕

          通過這個功能,我們就可以輕松的分析網(wǎng)頁,然后通過它的結(jié)構(gòu)來編寫爬蟲了。

          提取數(shù)據(jù)

          上面的response.html即是網(wǎng)頁的根節(jié)點(diǎn)HTML節(jié)點(diǎn),在節(jié)點(diǎn)對象上可以調(diào)用一些方法來檢索數(shù)據(jù)。最常用的方法是find方法,它通過CSS選擇器來定位數(shù)據(jù)。對于上面的例子,可以用find方法改寫第三段。

          因?yàn)樗胁檎曳椒ǚ祷氐慕Y(jié)果都是列表,所以如果你確定只需要查找一個,就將first參數(shù)設(shè)為真來只返回第一個結(jié)果。find方法返回的仍然是一個節(jié)點(diǎn),如果只需要節(jié)點(diǎn)的內(nèi)容,調(diào)用其text屬性即可。

          用戶名對應(yīng)的HTML結(jié)構(gòu)如圖所示。


          代碼如下。

          username = response.html.find('a.name', first=True).text

          除了find方法之外,還可以使用xpath方法用xpath語法來查找節(jié)點(diǎn),正如第一個例子那樣。我個人比較喜歡xpath語法,CSS選擇器雖然更加流行一些,但是寫出來的效果有點(diǎn)怪,不如xpath工整。

          同樣是這個頁面,看看如何獲取我的簡書的個人簡介。網(wǎng)頁代碼如圖所示。


          代碼如下。

          description=response.html.xpath(
              '//div[@class="description"]/div[@class="js-intro"]/text()', first=True)

          CSS選擇器和XPATH語法都不是本篇的主要內(nèi)容,如果你這方面不太熟悉,最好去看一下相關(guān)的教程。當(dāng)然如果大家有什么疑問的話,也可以提出來。假如大家想看的話,我也可以專門寫一篇文章介紹一下這些語法知識。


          渲染網(wǎng)頁

          有些網(wǎng)頁利用了前后端分離技術(shù)開發(fā)的,需要瀏覽器渲染才能完整顯示。如果用爬蟲去看的話,只能顯示一部分內(nèi)容。這時(shí)候就需要瀏覽器渲染頁面,才能獲取完整的頁面。用requests-html的話,這個過程非常簡單。

          首先先來看看一個需要渲染網(wǎng)頁的例子。下面的代碼訪問了我的簡書用戶頁面,然后嘗試獲取我的所有文章。但是如果你運(yùn)行這個例子的話,就會發(fā)現(xiàn)只能獲取前幾項(xiàng)。因?yàn)楹啎捻撁嬲且粋€典型的需要瀏覽器渲染的頁面,爬蟲獲取到的網(wǎng)頁是不完整的。

          from requests_html import HTMLSession
          
          session=HTMLSession()
          headers={
              'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.119 Safari/537.36'
          }
          
          url='https://www.jianshu.com/u/7753478e1554'
          r=session.get(url, headers=headers)
          
          for a in r.html.xpath('//ul[@class="note-list"]/li/div[@class="content"]/a[@class="title"]'):
              title=a.text
              link=f'https://www.jianshu.com{a.attrs["href"]}'
              print(f'《{title}》,{link}')
          

          那么如何渲染網(wǎng)頁來獲取完整的結(jié)果呢?其實(shí)非常簡單,在查詢HTML節(jié)點(diǎn)之前,調(diào)用render函數(shù)即可。


          render函數(shù)來使用瀏覽器渲染


          原理也非常簡單,第一次調(diào)用render的時(shí)候,requests-html會在本地下載一個chromium瀏覽器,用它來渲染網(wǎng)頁。如此一來,我們就可以獲取到渲染之后的頁面了。


          但是對于簡書這個例子來說還是有些問題,因?yàn)槿绻阍跒g覽器里打開這個網(wǎng)頁的話,會發(fā)現(xiàn)一些文章在瀏覽器下滑頁面的時(shí)候才開始渲染。不過聰慧的作者早就考慮到這種情況了,render函數(shù)支持下滑的參數(shù),設(shè)定之后,就會模擬瀏覽器下滑操作,從而解決了這個問題。

          r.html.render(scrolldown=50, sleep=0.2)

          節(jié)點(diǎn)對象

          不論上面的r.html還是find/xpath函數(shù)返回的結(jié)果,它們都是節(jié)點(diǎn)對象。除了上面介紹的幾個提取數(shù)據(jù)的方法以外,節(jié)點(diǎn)對象還有以下一些屬性,在我們提取數(shù)據(jù)的時(shí)候也有很大作用。



          相較于專業(yè)的爬蟲框架scrapy,或者僅用于解析XML的解析庫BeautifulSoup。requests-html可以是說恰到好處,它沒有前者那么難學(xué),也不像后者還需要搭配HTTP請求庫才能使用。如果你手頭需要臨時(shí)抓取幾個網(wǎng)頁,那么requests-html就是你最好的選擇。


          主站蜘蛛池模板: 中文字幕一区二区在线播放| 无码人妻久久一区二区三区免费| 亚洲V无码一区二区三区四区观看 亚洲爆乳精品无码一区二区三区 亚洲爆乳无码一区二区三区 | 麻豆AV一区二区三区久久| 国产天堂一区二区综合| 国产一区二区影院| 国产在线视频一区二区三区| 亚洲综合激情五月色一区| 亚洲AV无码一区二区三区牛牛| 伦精品一区二区三区视频| 无码中文人妻在线一区二区三区| 一区一区三区产品乱码| 在线精品视频一区二区| 亚洲av无码一区二区三区四区| 亚洲熟女综合一区二区三区| 麻豆国产在线不卡一区二区| 国产亚洲福利精品一区二区| 一区二区三区国模大胆| 国产一区二区精品尤物| 色久综合网精品一区二区| 国产精品亚洲午夜一区二区三区| 国产日韩一区二区三区在线播放| 老熟妇高潮一区二区三区| 视频在线一区二区三区| 一本大道东京热无码一区| 久久久国产精品亚洲一区| 亚洲欧美国产国产综合一区| 黑人一区二区三区中文字幕| 国产波霸爆乳一区二区| 亚洲视频一区网站| 日本免费一区尤物| 国产AⅤ精品一区二区三区久久 | 亚洲无线码一区二区三区| 99热门精品一区二区三区无码| 国产成人精品视频一区| 国产一区二区三区免费观在线| 老熟妇仑乱视频一区二区| 国产麻豆剧果冻传媒一区 | 国产在线观看一区精品| 精品无码成人片一区二区98| 麻豆精品一区二区综合av|