<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                [TOC] # Web頁面數據解析處理方法 > `urllib3`和`requests`庫都是圍繞支持`HTTP`協議實現`客戶端`功能。但是在對頁面解析處理上他們可能并不能提供更多的幫助,我們需要借助專門的Web頁面數據解析庫來解析并提取出結構化結果數據。 Web頁面的解析方法通常可以用下面三種方法: - `正則表達式` : 將頁面當做文本處理,簡單直接,大面積撒網。 - `XPath` : `XPath`路徑表達式可以讓我們像訪問目錄一樣訪問Web頁面的所有節點元素, 精準匹配。 - `CSS Selector` : CSS 選擇器`Selector` 與`XPath`相似,以CSS樣式的表達式來定位節點元素, 精準匹配。 ## 正則表達式 `Python`中的正則表達式庫`re` 是我們最為常用的正則庫,一條正則表達式可以幫我們過濾掉無用數據,只提取我們需要的格式數據。 在處理網頁時,我們并不會頻繁的全頁面匹配,可想而知這樣的效率極低,通常我們需要縮小數據匹配的范圍節點,在小范圍內進行正則匹配。而縮小范圍的方法常常會結合`XPath`或者`Selector`一起完成,所以要學會三種方法的配合使用。 有時候,可能一條正則表達式就可以提取出所有我們需要的結果,例如下面這個提取`IP:端口`的正則表達式: ```Python import requests import re url = 'https://free-proxy-list.net/anonymous-proxy.html' r = requests.get(url, timeout=10) pr_re = r'<td.*?>.*?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*?</td>.*?<td.*?>.*?(\d+).*?</td>' proxies = re.findall( pr_re, r.text) proxy_list=[] for proxy in proxies: proxy_list.append(':'.join(proxy[0:2])) print('\n'.join(proxy_list)) ``` ## `XPath` > `XPath`路徑表達式可以讓我們像訪問目錄一樣訪問Web頁面的所有節點元素, 精準匹配。 想了解`XPath`的詳細信息,可以閱讀[XPath快速了解](XPath快速了解.md),接下來我們說明下如何在`Python`中使用`XPath` 支持`XPath`的庫有`lxml`、`parsel` ,其實還有很多,只不過這兩個是`API`接口非常好用的庫。 `lxml`是基于C語言開發庫`libxml2`和`libxslt`實現的,因此速度上是非常快的(遠高于Python自帶的`ElementTree`,所以`ElementTree`很少被使用)。并且使用`cssselect`庫擴展支持了`CSS選擇器`接口。 `parsel`則是在`lxml`基礎上的更高級別封裝,并且提供了`XPath`、`CSSSelector`和`re`正則表達式三種提取方式的支持,封裝的接口也是更加簡單易用。同時,`parsel`也是`scrapy`所使用的選擇器。 ### lxml`XPath`解析示例 `XPath`表達式有時候我們不知道如何寫時,我們可以通過功瀏覽器的開發者工具幫助獲取`XPath`,具體方法為: `訪問目標URL` => 按`F12`打開開發者模式 => 選擇`Elements`tab頁 => 右鍵要定位的元素 => 選擇`Copy`中的`Copy XPath`。 如下圖所示: ![xpath](https://img.kancloud.cn/1d/cc/1dcce1d6d7bf625c949f406b690bc072_841x729.png =300x) 通過此方法得到的`XPath`,可能很長,或者冗余信息太多,我們只需要在得到的`XPath`表達式上進行優化即可。 #### 示例一:簡單的xpath使用提取博客文章列表 ```Python import requests as req from lxml import etree url='https://www.learnhard.cn/feed' resp = req.get(url) doc = etree.HTML(resp.content) items = doc.xpath('//item/title/text()') print('\n'.join(items)) ``` #### 示例二:獲取微博實時熱搜排行榜 > 微博實時熱搜的`cookies`信息需要設置一下,不用登錄。 ```Python import requests as req from lxml import etree import re headers = { 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', 'authority': 'weibo.com', 'cookie': 'UM_distinctid=171437c9856a47-0cd9abe048ffaf-1528110c-1fa400-171437c9857ac3; CNZZDATA1272960323=1824617560-1569466214-%7C1595951362; SCF=AhjAkJNek3wkLok6WSbiibV1WsGffKPYsDlTZtFqiUH_YWL81nk-0xKkiukxpRoDMoIoV0IClwWecgXLLPiBZrw.; SUHB=0gHTlGutSIGq9P; ALF=1628229198; SUB=_2AkMoasG0f8NxqwJRmfoUxG7ibIl_ww7EieKeNjBvJRMxHRl-yT9jqlYktRB6A-rvW2hROYk5DlHgX7r_dk67bcEdfhBN; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9WWh..ORuiFeK.mEWDWeecX1; SINAGLOBAL=1133654064055.2583.1597394566906; UOR=,,www.comicyu.com; login_sid_t=f855cdd8714fdb25dee824ce5ff8d792; cross_origin_proto=SSL; Ugrow-G0=6fd5dedc9d0f894fec342d051b79679e; TC-V5-G0=4de7df00d4dc12eb0897c97413797808; wb_view_log=1914*10771.0026346445083618; _s_tentry=weibo.com; Apache=4531467438705.743.1597800659782; ULV=1597800659793:3:2:1:4531467438705.743.1597800659782:1597394566920; TC-Page-G0=d6c372d8b8b800aa7fd9c9d95a471b97|1597800912|1597800912; WBStorage=42212210b087ca50|undefined' } def main(): url='https://weibo.com/a/hot/realtime' resp = req.get(url, headers = headers) doc = etree.HTML(resp.text) topic_list = doc.xpath('//div[@class="UG_content_row"]') for topic in topic_list: desc = topic.xpath('.//div[@class="list_des"]')[0] topic_title = desc.xpath('h3[@class="list_title_b"]/a/text()')[0].strip() subinfo = desc.xpath('./div')[0].xpath('string(.)').strip().replace(' ','') subinfo = re.sub('\s+',',', subinfo) subinfo = re.findall(r'(.*?),(.*?),.*?([0-9]*?),.*?([0-9]*?),.*?([0-9]+)', subinfo)[0] print(topic_title + ',' + ','.join(subinfo)) if __name__ == '__main__': main() ``` 運行結果: ```sh python ./demo_weibo_realtime.py 特朗普反擊奧巴馬夫人,徐子森先生,今天11:39,10,54,11789 ... 迪麗熱巴廣州,芒果娛樂,今天21:30,1786,2600,31562 ``` ### parsel`XPath`解析示例 我們以微博實時熱門關鍵詞為例: ```Python import requests as req from parsel import Selector import re headers = { 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', 'authority': 'weibo.com', 'cookie': 'UM_distinctid=171437c9856a47-0cd9abe048ffaf-1528110c-1fa400-171437c9857ac3; CNZZDATA1272960323=1824617560-1569466214-%7C1595951362; SCF=AhjAkJNek3wkLok6WSbiibV1WsGffKPYsDlTZtFqiUH_YWL81nk-0xKkiukxpRoDMoIoV0IClwWecgXLLPiBZrw.; SUHB=0gHTlGutSIGq9P; ALF=1628229198; SUB=_2AkMoasG0f8NxqwJRmfoUxG7ibIl_ww7EieKeNjBvJRMxHRl-yT9jqlYktRB6A-rvW2hROYk5DlHgX7r_dk67bcEdfhBN; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9WWh..ORuiFeK.mEWDWeecX1; SINAGLOBAL=1133654064055.2583.1597394566906; UOR=,,www.comicyu.com; login_sid_t=f855cdd8714fdb25dee824ce5ff8d792; cross_origin_proto=SSL; Ugrow-G0=6fd5dedc9d0f894fec342d051b79679e; TC-V5-G0=4de7df00d4dc12eb0897c97413797808; wb_view_log=1914*10771.0026346445083618; _s_tentry=weibo.com; Apache=4531467438705.743.1597800659782; ULV=1597800659793:3:2:1:4531467438705.743.1597800659782:1597394566920; TC-Page-G0=d6c372d8b8b800aa7fd9c9d95a471b97|1597800912|1597800912; WBStorage=42212210b087ca50|undefined' } def main(): url='https://weibo.com/a/hot/realtime' resp = req.get(url, headers = headers) # print(resp.text) selector = Selector(resp.text) topic_list = selector.xpath('//div[@class="UG_content_row"]') for topic in topic_list: desc = topic.xpath('.//div[@class="list_des"]') topic_title = desc.xpath('h3[@class="list_title_b"]/a/text()').get().strip() subinfo = desc.xpath('./div').xpath('string(.)').get().strip().replace(' ','') subinfo = re.sub('\s+',',', subinfo) subinfo = re.findall(r'(.*?),(.*?),.*?([0-9]*?),.*?([0-9]*?),.*?([0-9]+)', subinfo)[0] print(topic_title + ',' + ','.join(subinfo)) if __name__ == '__main__': main() ``` 與`lxml`的示例比較可以發現,兩者使用方法非常相近,`parsel`的`xpath()`方法每次返回的都是`SelectorList`對象實例,當需要提取節點值時使用`get()`或者`getall()`方法解析,前者返回單個值,而后者返回一個列表,及時只有一個結果也會返回列表。 ## CSSSelector > `CSS`是`HTML`頁面的樣式描述語言,`CSS選擇器`其實就是用樣式特征來定位元素。 關于`CSS選擇器`詳細語法可以閱讀 [CSS選擇器參考手冊](CSS選擇器參考手冊.md) 這一節。 在你掌握了`CSS選擇器`語法后,接下來就來了解如何在`Python`中使用它。 `Python`中支持`CSS選擇器`的庫包含了`lxml`和`parsel`和`pyquery`,他們內部都是依賴于`cssselect`庫實現。`cssselect`庫原本是`lxml`的一個模塊,后來獨立成為一個項目,但我們依然可以在`lxml.cssselect`中使用它。 支持`CSS選擇器`的庫還有`bs4`, `bs4`依賴 `soupsieve`庫實現`CSS選擇器功能`。 同樣的,我們以示例作為學習參考來了解如何使用`CSS選擇器`。 ### lxml中的`CSS選擇器`用法 通過調用`cssselect()`方法使用`CSS選擇器`表達式,如下面示例用于提取博客文章列表信息: ```Python import requests as req from lxml import etree url='https://www.learnhard.cn' resp = req.get(url) doc = etree.HTML(resp.content) title_list = doc.cssselect('article > header > h2 > a') for item in title_list: title = item.xpath('string(.)').strip() url = item.xpath('./@href')[0] print(f'- [{title}]({url})') ``` ### `bs4`中的`CSS選擇器`用法 通過調用`select()`方法使用`CSS選擇器`表達式,如下面示例用于提取博客文章列表信息: ```Python import requests as req from bs4 import BeautifulSoup as bs url='https://www.learnhard.cn' resp = req.get(url) soup = bs(resp.content, 'lxml') item_list = soup.select('article > header > h2 > a') for item in item_list: title = item.get_text().strip() # url = item.attrs['href'] url = item['href'] print(f'- [{title}]({url})') ``` `bs4`可以讓我們訪問一個實例的屬性一樣來訪問標簽元素及其屬性信息,如本例中我們獲取`url`地址時是通過`item.a['href']`獲取當前元素下`<a>`標簽中`@href`屬性值。 ### `pyquery`中的`CSS選擇器`用法 ```Python import requests as req from pyquery import PyQuery as pq url='https://www.learnhard.cn' resp = req.get(url) query = pq(resp.content) item_list = query('article > header > h2 > a') for item in item_list: title = item.text url = item.attrib['href'] print(f'- [{title}]({url})') ``` ### `parsel`中的`CSS選擇器`用法 ```Python import requests as req from parsel import Selector url='https://www.learnhard.cn' resp = req.get(url) sel = Selector(resp.text) title_list = sel.css('article > header > h2 > a') for item in title_list: title = item.css('::text').get() url = item.css('::attr("href")').get() # url = item.attrib['href'] print(f'- [{title}]({url})') ``` 看到這里,你會發現`parsel`的文本和屬性被當做(偽)節點處理了,這與其他的處理方式都不同,但是這樣的好處也顯而易見,我們處理屬性和文本變得更加直觀容易了。 關于`CSS選擇器`需要說明的是,多數的`偽類`和`偽元素`選擇器是不支持的,例如`p:first-child` 和 `p::first-line`。雖然如此,支持的`CSS選擇器`已經提供了足夠的功能。`cssselect`的文檔中有詳細說明[Supported selectors](https://cssselect.readthedocs.io/en/latest/#supported-selectors)。 另外`cssselect`支持一些不在`CSS`規范中的選擇器: - `:contains(text)`偽類選擇器 - `[foo!=bar]`中的`!=`屬性操作符,等同于`:not([foo=bar])`。 - `:scope` 允許訪問選擇器的直接子級, 但是必須放在最開頭位置, `:scope > div::text` - 命名空間的用法`ns|div` --- ~END~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看