Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 中文字幕一区二区在线视频 ,日韩免费高清视频网站,亚洲欧美日韩在线中文字幕

          整合營(yíng)銷服務(wù)商

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

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

          從0學(xué)爬蟲(chóng)-頁(yè)面解析的幾種方法

          從0學(xué)爬蟲(chóng)-頁(yè)面解析的幾種方法

          話不多說(shuō),直接進(jìn)入正題。

          一。首先是xpath。

          1.官方的來(lái)講就是能在xml樹(shù)狀結(jié)構(gòu)中尋找節(jié)點(diǎn) xpath用于在xml文檔中通過(guò)元素和屬性進(jìn)行導(dǎo)航和定位。

          2.解析網(wǎng)頁(yè),對(duì)于一些網(wǎng)頁(yè)結(jié)構(gòu)比較明顯的我們一般都采用xpath去進(jìn)行解析。

          3.快速入門

          from lxml import etree
          # html網(wǎng)頁(yè)源代碼
          html="""
                  <div>
                      <ul>
                           <li class="item-0"><a href="link1.html">first item</a></li>
                           <li class="item-1"><a href="link2.html">second item</a></li>
                           <li class="item-inactive"><a href="link3.html">third item</a></li>
                           <li class="item-1"><a href="link4.html">fourth item</a></li>
                           <li class="item-0"><a href="link5.html">fifth item</a>
                       </ul>
                   </div>
                  """
          # 將html轉(zhuǎn)成xml
          element=etree.HTML(html)
          # print(element)
          # 獲取li標(biāo)簽下面的a標(biāo)簽的href屬性值
          links=element.xpath('//ul/li/a/@href')
          print(links)  # 列表
          # 獲取li標(biāo)簽下面的a標(biāo)簽的文本數(shù)據(jù)
          titles=element.xpath('//ul/li/a/text()')
          print(titles)

          結(jié)果如下:

          二。BS4

          BS4也是一種解析方式,原理基本類似xpath。兩者相對(duì)比,xpath需要記住一些語(yǔ)法,bs4則只需要記住一些方法就可以了,掌握Beautifulsoup這個(gè)核心類就ok了。

          ● 安裝

          ○ pip install lxml

          ○ pip install bs4 bs4這個(gè)庫(kù)對(duì)我們的lxml存在依賴

          詳細(xì)使用可以參考中文文檔地址:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/

          一般常用的find_all和find就能應(yīng)對(duì)大部分情況。

          import requests
          from bs4 import BeautifulSoup
          #解析
          soup=BeautifulSoup(text,'html5lib') #這里一般采用 lxml ,也可以使用html5lib
          #獲取單個(gè)標(biāo)簽
          aa=soup.find('div', id="container")
          #獲取標(biāo)簽下所有的下一級(jí)標(biāo)簽
          list=aa.find_all('div', class_="box picblock col3")

          三。urllib

          保存圖片很好用,其他情況使用不多。

          獲取請(qǐng)求示例:

          import urllib.request
          url='需要訪問(wèn)的網(wǎng)頁(yè)地址'
          headers={
              'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
          }
          # 1 創(chuàng)建req請(qǐng)求對(duì)象并構(gòu)建headers
          req=urllib.request.Request(url,headers=headers)
          print(req)  # <urllib.request.Request object at 0x0000022D35B9BB88>
          # 2 獲取響應(yīng)數(shù)據(jù)
          response=urllib.request.urlopen(req)
          # 3 讀取響應(yīng)內(nèi)容
          html=response.read().decode('utf-8')
          print(html)

          保存圖片示例:

          是入門理論的最后一部分,完成了這一步就可以說(shuō)是完成了一個(gè)簡(jiǎn)單的爬蟲(chóng)。用來(lái)解析響應(yīng)中的Html文件的Python模塊由很多,解析方式也有所不同。據(jù)我觀察beautifulsoup的使用應(yīng)該比lxml更加普及(我沒(méi)有做過(guò)系統(tǒng)的調(diào)查,這個(gè)結(jié)果是根據(jù)查找到的資料數(shù)量來(lái)的),但是如何選擇還要看使用者自己的喜好。

          beautifulsoup(bs4)

          beautifulsoup(下稱bs4)使用Python編寫(xiě),使用相較于lxml較容易,但是效率也較低。不過(guò)bs4支持很多解析器,lxml也是其中一種。

          1 解析器

          上文說(shuō)到bs4支持很多解析器,我們?cè)诖肆谐觯?/p>

          -Python自帶的標(biāo)準(zhǔn)庫(kù)“html.parser”:因?yàn)槭莾?nèi)置的庫(kù)所以使用簡(jiǎn)單,但在Python2.7.3/3.2.2之前容錯(cuò)能力差

          -lxml解析器“l(fā)xml”:速度快容錯(cuò)高,但是需要安裝C語(yǔ)言庫(kù)

          -lxmlXML解析器“l(fā)xml-xml”/“xml”:速度快支持XML,也需要安裝C語(yǔ)言庫(kù)

          -html5lib解析器“html5lib”:速度慢但會(huì)以瀏覽器的形式解析文檔

          至于bs4解析HTML文檔只需要小小的一步:

          from bs4 import BeautifulSoup
          soup_html=BeautifulSoup(你的html文本,"解析器,也就是我剛剛介紹里的粗體部分,也可以不填讓bs4自己選擇")

          2 四類對(duì)象

          bs4會(huì)將html文本轉(zhuǎn)換成一個(gè)樹(shù)形結(jié)構(gòu),而結(jié)構(gòu)里的對(duì)象有四種,分別是Tag(標(biāo)簽)、NavigableString(字符串)、BeautifulSoup和Comment(注釋)。下面我們分別解釋這四類對(duì)象在html文本中的含義。

          -Tag:tag的意思就是標(biāo)簽,它與html文本中的標(biāo)簽同義。BeautifulSoup對(duì)象也可以被看做是一個(gè)Tag。Tag中屬性的訪問(wèn)方法如同字典,比如訪問(wèn)Tag對(duì)象a的href屬性的寫(xiě)法為a[‘href’]。

          -NavigableString:html文本中所有的字符內(nèi)容(就是除了標(biāo)簽之外被直接展示出來(lái)的文字)都是NavigableString。

          -BeautifulSoup:它就是完整的一個(gè)html文本,可以被看做一個(gè)特殊的Tag。

          -Comment:注釋,也可以被當(dāng)做NavigableString被.string訪問(wèn)到。

          判斷一個(gè)子節(jié)點(diǎn)對(duì)象類型的方法:type(soup_html)==bs4.element.對(duì)象名

          3 篩選函數(shù)

          在將html文本轉(zhuǎn)換成對(duì)象樹(shù)之后,bs4會(huì)提供一系列方法來(lái)查詢它們。下面會(huì)列舉出一些常用的方法。

          -BeautifulSoup.prettify():得到格式化的標(biāo)準(zhǔn)縮進(jìn)的html文本。

          -Tag.Tagname:用.運(yùn)算符會(huì)返回第一個(gè)標(biāo)簽名為Tagname的標(biāo)簽。

          -Tag.name:返回此標(biāo)簽的名字(按照這個(gè)寫(xiě)法可能有點(diǎn)多余,但是如果是你不知道標(biāo)簽名的soup呢?)

          -Tag.contents:獲得所有子標(biāo)簽的列表。

          -Tag.parents:獲得所有父標(biāo)簽的列表。

          -Tag.string:獲得標(biāo)簽內(nèi)部的文字。(只在標(biāo)簽內(nèi)僅有一個(gè)NavigableString對(duì)象的時(shí)候返回值,否則為None)

          -Tag.strings:獲得所有文字列表。

          -Tag.stripped_strings:獲得去掉換行符和空格的文字列表。

          -Tag.Tagname[‘Attrname’]:返回第一個(gè)Tagname標(biāo)簽的Attrname屬性的值。

          -Tag.find(attr=”attrname”[,”tagname”]):這個(gè)方法查找第一個(gè)符合條件的標(biāo)簽其屬性attr值等于attrname。

          -Tag.find_all(attr=”attrname”[,]):同上,不過(guò)返回的是所有符合條件的標(biāo)簽。對(duì)于find與find_all函數(shù),當(dāng)attr為class時(shí)需要寫(xiě)作class_,這是為了避開(kāi)保留字。

          lxml

          相較于beautifulsoup而言lxml使用C語(yǔ)言編寫(xiě)(而且beautifulsoup一次要讀取整個(gè)DOM),所以在運(yùn)行效率和速度等方面lxml是當(dāng)之無(wú)愧的優(yōu)勢(shì)。但是lxml采用XPath解析HTML和XML文件,所以如果要用lxml對(duì)HTML進(jìn)行解析還要先學(xué)習(xí)XPath。

          1 XPath

          XPath全稱為XML Path Language,也就是XML路徑(解析)語(yǔ)言。顧名思義它最初被設(shè)計(jì)用于XML文件的搜索,但是現(xiàn)在也支持HTML。

          學(xué)習(xí)XPath的成本(初步運(yùn)用)應(yīng)與學(xué)習(xí)正則表達(dá)式類似。(這是個(gè)人觀點(diǎn))

          2 XPath基本常用語(yǔ)法

          關(guān)于XPath的概念等我們限于篇幅就不展示了,請(qǐng)自行尋找資料學(xué)習(xí)。以下列出的是在爬蟲(chóng)領(lǐng)域較為常用的語(yǔ)法。

          -nodename:選取nodename節(jié)點(diǎn)的所有子節(jié)點(diǎn)

          -/:選取根節(jié)點(diǎn)

          -//:從當(dāng)前節(jié)點(diǎn)選取任意位置節(jié)點(diǎn)

          -.:選取當(dāng)前節(jié)點(diǎn)

          -..:選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)

          -@:選取屬性

          -[]:XPath中的“謂語(yǔ)”,也就是查找條件

          -*:匹配任何元素節(jié)點(diǎn)

          -@*:匹配任何屬性節(jié)點(diǎn)

          -node():匹配任何節(jié)點(diǎn)

          -text():獲取文本內(nèi)容

          3 lxml解析html

          from lxml import etree
          html_lxml=etree.HTML(html) #將html文本變成lxml的對(duì)象
          html_lxml.xpath("XPath表達(dá)式") #用XPath搜索對(duì)象

          4 例 XPath的運(yùn)用

          以bs4官網(wǎng)教程里的一段html(愛(ài)麗絲文檔)為例,我將寫(xiě)出這段文本里部分元素節(jié)點(diǎn)的XPath以供讀者參考。你也可以使用chrome的開(kāi)發(fā)者工具->copy->copyXPath獲得頁(yè)面中標(biāo)簽的XPath。

          義上講,爬蟲(chóng)只負(fù)責(zé)抓取,也就是下載網(wǎng)頁(yè)。而實(shí)際上,爬蟲(chóng)還要負(fù)責(zé)從下載的網(wǎng)頁(yè)中提取我們想要的數(shù)據(jù),即對(duì)非結(jié)構(gòu)化的數(shù)據(jù)(網(wǎng)頁(yè))進(jìn)行解析提取出結(jié)構(gòu)化的數(shù)據(jù)(有用數(shù)據(jù))。

          所以說(shuō),網(wǎng)頁(yè)下載下來(lái)只是第一步,還有重要的一步就是數(shù)據(jù)提取。不同的爬蟲(chóng)想要的數(shù)據(jù)不一樣,提取的數(shù)據(jù)也就不一樣,但提取方法都是類似的。

          最簡(jiǎn)單的提取數(shù)據(jù)的方法,就是使用正則表達(dá)式,此種方法簡(jiǎn)單,提取的邏輯也不能復(fù)雜,不然寫(xiě)出的正則表達(dá)式就晦澀難懂,甚至不能提取復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。

          最終,老猿經(jīng)過(guò)多年的使用經(jīng)驗(yàn),選擇了lxml和xpath來(lái)解析網(wǎng)頁(yè)提取結(jié)構(gòu)化數(shù)據(jù)。順便說(shuō)一下 BeautifulSoup,它也是一個(gè)很棒的解析HTML的工具,可以使用多個(gè)解析器,比如Python標(biāo)準(zhǔn)庫(kù)的parser,但是速度比較慢,也可以使用lxml作為解析器,但是它的使用方法、API跟lxml不太一樣。使用下來(lái),還是lxml的API更舒服。

          lxml 對(duì)C語(yǔ)言庫(kù) libxml2和 libxslt進(jìn)行綁定,提供了Pythonic的API,它有一些主要特點(diǎn):

          • 支持標(biāo)準(zhǔn)的XML
          • 支持(損壞)的HTML
          • 非??斓慕馕鏊俣?/li>
          • Pythonic的API更易于使用
          • 使用Python的unicode字符串
          • 內(nèi)存安全(沒(méi)有段錯(cuò)誤)
          • 不需要手動(dòng)管理內(nèi)存

          總結(jié)為一句話就是,C語(yǔ)言的速度和Python的簡(jiǎn)易相結(jié)合的神器。

          lxml有兩大部分,分別支持XML和HTML的解析:

          • lxml.etree 解析XML
          • lxml.html 解析html

          lxml.etree可以用來(lái)解析RSS feed,它就是一個(gè)XML格式的文檔。然而爬蟲(chóng)抓取的絕大部分都是html網(wǎng)頁(yè),所以,我們這里主要講述lxml.html解析網(wǎng)頁(yè)的方法。

          lxml.html 從html字符串生成文檔樹(shù)結(jié)構(gòu)

          我們下載得到的網(wǎng)頁(yè)就是一串html字符串,如何把它輸入給lxml.html模塊,從而生成html文檔的樹(shù)結(jié)構(gòu)呢?

          該模塊提供了幾種不同的方法:

          • parse(filename_url_or_file):
          • 輸入的是一個(gè)文件名、URL或文件對(duì)象(有read()方法)。
          • document_fromstring(string):
          • 輸入的是一個(gè)html的字符串,創(chuàng)建一個(gè)HTML文檔樹(shù)結(jié)構(gòu),它的根節(jié)點(diǎn)就是, 和 子節(jié)點(diǎn)。
          • fragment_fromstring(string, create_parent=False):
          • 返回輸入字符串的HTML片段。這個(gè)片段壁紙只含有一個(gè)element(元素),也就是單一節(jié)點(diǎn),除非給出了create_parent 參數(shù),否則會(huì)報(bào)錯(cuò)。
          • fragments_fromstring(string):
          • 返回包含輸入字符串中所有片段的列表。
          • fromstring(string):
          • 返回值依據(jù)輸入字符串而定,如果輸入看起來(lái)像是一個(gè)文檔,則返回document_fromstring(string),如果是一個(gè)單一片段,則返回fragment_fromstring(string)。

          下面我們通過(guò)具體示例來(lái)說(shuō)明上面幾個(gè)方法的不同。

          document_fromstring 的使用方法

          In [1]: import lxml.html as lh
          In [2]: z=lh.document_fromstring('<span>abc</span><span>xyz</span>')
          # 可以看到,它自動(dòng)加了根節(jié)點(diǎn)<html>
          In [3]: z
          Out[3]: <Element html at 0x7fc410667b88>
          In [4]: z.tag
          Out[4]: 'html'
          # 還加了<body>節(jié)點(diǎn)
          In [5]: z.getchildren()
          Out[5]: [<Element body at 0x7fc4101a3ae8>]
          # 把字符串的兩個(gè)節(jié)點(diǎn)放在了<body>里面
          In [6]: z.getchildren()[0].getchildren()
          Out[6]: [<Element span at 0x7fc410092bd8>, <Element span at 0x7fc410667c28>]
          

          fragment_fromstring 的使用

          In [11]: z=lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’)
          ---------------------------------------------------------------------------
          ParserError Traceback (most recent call last)
          <ipython-input-11-a11f9a0f71d1> in <module>()
          ----> 1 z=lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’)
          ~/.virtualenvs/py3.6/lib/python3.6/site-packages/lxml/html/__init__.py in fragment_fromstring(html, create_parent, base_url, parser, **kw)
           850 raise etree.ParserError(
           851 “Multiple elements found (%s)”
          --> 852 % ‘, ‘.join([_element_name(e) for e in elements]))
           853 el=elements[0]
           854 if el.tail and el.tail.strip():
          ParserError: Multiple elements found (div, div)
          # 可以看到,輸入是兩個(gè)節(jié)點(diǎn)(element)時(shí)就會(huì)報(bào)錯(cuò)
          # 如果加上 create_parent 參數(shù),就沒(méi)問(wèn)題了
          In [12]: z=lh.fragment_fromstring('<div>abc</div><div>xyz</div>', create_parent='p')
          In [13]: z.tag
          Out[13]: 'p'
          In [14]: z.getchildren()
          Out[14]: [<Element div at 0x7fc40a41a818>, <Element div at 0x7fc40a41aea8>]
          

          fragments_fromstring 的使用

          # 輸入字符串含有一個(gè)節(jié)點(diǎn),則返回包含這一個(gè)節(jié)點(diǎn)的列表
          In [17]: lh.fragments_fromstring('<div>abc</div>')
          Out[17]: [<Element div at 0x7fc40a124ea8>]
          # 輸入字符串含有多個(gè)節(jié)點(diǎn),則返回包含這多個(gè)節(jié)點(diǎn)的列表
          In [18]: lh.fragments_fromstring('<div>abc</div><div>xyz</div>')
          Out[18]: [<Element div at 0x7fc40a124b88>, <Element div at 0x7fc40a124f98>]
          

          fromstring 的使用

          In [27]: z=lh.fromstring('<div>abc</div><div>xyz</div>')
          In [28]: z
          Out[28]: <Element div at 0x7fc40a0eb368>
          In [29]: z.getchildren()
          Out[29]: [<Element div at 0x7fc410135548>, <Element div at 0x7fc40a0eb2c8>]
          In [30]: type(z)
          Out[30]: lxml.html.HtmlElement
          

          這里,fromstring輸入的如果是多個(gè)節(jié)點(diǎn),它會(huì)給加一個(gè)父節(jié)點(diǎn)并返回。但是像html網(wǎng)頁(yè)都是從節(jié)點(diǎn)開(kāi)始的,我們使用fromstring() 和 document_fromstring() 都可以得到完整的網(wǎng)頁(yè)結(jié)構(gòu)。

          從上面代碼中我們可以看到,那幾個(gè)函數(shù)返回的都是HtmlElement對(duì)象,也就是說(shuō),我們已經(jīng)學(xué)會(huì)了如何從html字符串得到HtmlElement的對(duì)象,下一節(jié)我們將學(xué)習(xí)如何操作HtmlElement對(duì)象,從中提取我們感興趣的數(shù)據(jù)。


          主站蜘蛛池模板: 女同一区二区在线观看| 国模极品一区二区三区| 精品亚洲AV无码一区二区| 夜色福利一区二区三区| 亚洲国产系列一区二区三区| 无码人妻精品一区二区三区9厂 | 亚洲AV无码一区东京热| 日韩一区二区视频在线观看| 精品理论片一区二区三区| 亚洲一区二区精品视频| 91在线精品亚洲一区二区| 性色av无码免费一区二区三区| 精品视频在线观看你懂的一区 | 国产精品熟女视频一区二区| 无码精品人妻一区二区三区影院| 国产综合精品一区二区三区| 色噜噜狠狠一区二区三区| 无码人妻AⅤ一区二区三区水密桃 无码欧精品亚洲日韩一区夜夜嗨 无码毛片一区二区三区中文字幕 无码毛片一区二区三区视频免费播放 | 欧洲精品一区二区三区在线观看| 国产精品亚洲不卡一区二区三区| 夜夜嗨AV一区二区三区| 久久久久人妻精品一区三寸| 在线观看免费视频一区| 精品人妻少妇一区二区三区不卡 | 国产欧美一区二区精品仙草咪 | 精品国产AV无码一区二区三区 | 国产视频一区二区| 亚洲AV无码一区东京热久久 | 中文字幕一精品亚洲无线一区| 成人精品一区二区户外勾搭野战 | 无码日韩人妻AV一区二区三区| 色老头在线一区二区三区| 卡通动漫中文字幕第一区| 精品无码日韩一区二区三区不卡| 日本精品一区二区三区四区| 中文字幕日韩丝袜一区| 人妻少妇AV无码一区二区| 日本精品一区二区三区视频| 91精品一区二区| 一本AV高清一区二区三区| 国产女人乱人伦精品一区二区|