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 亚洲国产成人精品久久,亚洲男男猛男xxx,成人网在线视频

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

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

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

          Python: 爬蟲(chóng)網(wǎng)頁(yè)解析工具lxml.html(一)

          義上講,爬蟲(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ù)。

          發(fā)送HTTP請(qǐng)求:首先,你需要向目標(biāo)網(wǎng)頁(yè)發(fā)送HTTP請(qǐng)求以獲取其HTML內(nèi)容。這可以通過(guò)Java的內(nèi)置庫(kù)java.net.HttpURLConnection或者使用更高級(jí)的庫(kù)如Apache Http Client OkHttp等來(lái)完成。

          ·讀取響應(yīng)內(nèi)容:一旦你發(fā)送了請(qǐng)求并收到了響應(yīng),你需要讀取響應(yīng)的內(nèi)容,這通常是HTML格式的字符串。

          ·解析HTML:然后,你需要解析HTML字符串以提取所需的信息,這可以通過(guò)正則表達(dá)式來(lái)完成。但通常建議使用專門的HTML解析庫(kù),如Jsoup。Jsoup提供了一種非常方便的方式來(lái)解析HTML文檔,并可以通過(guò)類似于CSS或jQuery的選擇器語(yǔ)法來(lái)提取和操作數(shù)據(jù)。

          ·如果你需要處理更復(fù)雜的網(wǎng)頁(yè)或進(jìn)行更高級(jí)的網(wǎng)頁(yè)抓取和解析任務(wù),你可能還需要考慮使用如Selenium這樣的瀏覽器自動(dòng)化工具來(lái)模擬真實(shí)的瀏覽器行為。但是請(qǐng)注意,頻繁或大規(guī)模地抓取網(wǎng)頁(yè)可能會(huì)違反網(wǎng)站的使用條款甚至可能構(gòu)成法律問(wèn)題。

          解析HTML文檔,可以使用一些編程語(yǔ)言中的HTML解析庫(kù)或工具。以下是一些常用的方法:

          1. 使用Python中的BeautifulSoup庫(kù):BeautifulSoup是一個(gè)功能強(qiáng)大的HTML解析庫(kù),可以幫助你從HTML文檔中提取數(shù)據(jù)。你可以使用pip安裝BeautifulSoup,然后使用它的解析器來(lái)解析HTML文檔。
          from bs4 import BeautifulSoup
          
          # 讀取HTML文檔
          with open('example.html', 'r') as file:
              html = file.read()
          
          # 創(chuàng)建BeautifulSoup對(duì)象
          soup = BeautifulSoup(html, 'html.parser')
          
          # 使用BeautifulSoup對(duì)象提取數(shù)據(jù)
          # 例如,提取所有的鏈接
          links = soup.find_all('a')
          for link in links:
              print(link.get('href'))
          
          1. 使用JavaScript中的DOM解析器:如果你在瀏覽器環(huán)境中,可以使用JavaScript的DOM解析器來(lái)解析HTML文檔。你可以使用document對(duì)象來(lái)訪問(wèn)和操作HTML元素。
          // 讀取HTML文檔
          var html = document.documentElement.innerHTML;
          
          // 使用DOM解析器提取數(shù)據(jù)
          // 例如,提取所有的鏈接
          var links = document.getElementsByTagName('a');
          for (var i = 0; i < links.length; i++) {
              console.log(links[i].getAttribute('href'));
          }
          
          1. 使用其他編程語(yǔ)言的HTML解析庫(kù):除了Python和JavaScript,還有許多其他編程語(yǔ)言也有自己的HTML解析庫(kù),例如Java中的Jsoup、Ruby中的Nokogiri等。你可以根據(jù)自己的編程語(yǔ)言選擇適合的HTML解析庫(kù)來(lái)解析HTML文檔。

          無(wú)論你選擇哪種方法,解析HTML文檔的關(guān)鍵是了解HTML的結(jié)構(gòu)和標(biāo)簽,并使用相應(yīng)的解析器或工具來(lái)提取所需的數(shù)據(jù)。

          當(dāng)你解析HTML文檔時(shí),你可能會(huì)遇到以下一些常見(jiàn)的任務(wù)和技術(shù):

          1. 選擇器:使用選擇器可以方便地定位和提取HTML文檔中的特定元素。例如,你可以使用CSS選擇器來(lái)選擇具有特定類名或ID的元素,或者使用XPath來(lái)選擇具有特定屬性或?qū)哟谓Y(jié)構(gòu)的元素。
          2. 提取數(shù)據(jù):一旦你定位到了要提取的元素,你可以使用相應(yīng)的方法或?qū)傩詠?lái)獲取元素的文本內(nèi)容、屬性值或其他相關(guān)信息。例如,你可以使用getText()方法來(lái)獲取元素的文本內(nèi)容,使用getAttribute()方法來(lái)獲取元素的屬性值。
          3. 遍歷文檔:HTML文檔通常是一個(gè)樹(shù)狀結(jié)構(gòu),你可以使用遍歷方法來(lái)訪問(wèn)和操作文檔中的不同元素。例如,你可以使用遞歸或循環(huán)來(lái)遍歷文檔的子元素、父元素或兄弟元素。
          4. 處理嵌套結(jié)構(gòu):HTML文檔中的元素可能會(huì)有嵌套的結(jié)構(gòu),你需要處理這些嵌套關(guān)系來(lái)正確地提取數(shù)據(jù)。例如,你可以使用遞歸方法來(lái)處理嵌套的列表、表格或嵌套的div元素。
          5. 處理特殊情況:在解析HTML文檔時(shí),可能會(huì)遇到一些特殊情況,例如處理動(dòng)態(tài)生成的內(nèi)容、處理特殊字符或處理錯(cuò)誤的HTML結(jié)構(gòu)。你需要根據(jù)具體情況選擇合適的方法來(lái)處理這些特殊情況。

          總的來(lái)說(shuō),解析HTML文檔需要一定的HTML知識(shí)和編程技巧。你需要了解HTML的結(jié)構(gòu)和標(biāo)簽,選擇合適的解析器或工具,使用選擇器來(lái)定位元素,提取所需的數(shù)據(jù),并處理特殊情況。通過(guò)不斷練習(xí)和實(shí)踐,你將能夠更熟練地解析HTML文檔并提取所需的數(shù)據(jù)。


          主站蜘蛛池模板: 亚洲午夜电影一区二区三区 | 精品国产一区二区三区四区| 国产在线一区二区三区av| 国产日韩AV免费无码一区二区三区| 高清一区二区三区日本久| 久久精品免费一区二区喷潮| 国产色情一区二区三区在线播放| 精品久久综合一区二区| 色狠狠一区二区三区香蕉| 国产一区二区精品| 精品福利一区二区三区| 国产激情一区二区三区小说| 国产激情视频一区二区三区| 国产在线视频一区| 香蕉在线精品一区二区| 一区二区三区杨幂在线观看| 午夜福利国产一区二区| 激情爆乳一区二区三区| 理论亚洲区美一区二区三区| 国产Av一区二区精品久久| 亚洲欧美一区二区三区日产| 3D动漫精品啪啪一区二区下载| 精品一区二区三区东京热| 99久久精品国产一区二区成人| 无码人妻少妇色欲AV一区二区 | 性色av无码免费一区二区三区| 无码人妻精品一区二区三区99性| 国产香蕉一区二区在线网站| 男插女高潮一区二区| 天堂va在线高清一区| 无码av中文一区二区三区桃花岛| 精品久久久中文字幕一区| 日本在线视频一区| 国产精品免费一区二区三区| 伊人久久大香线蕉av一区| 亚洲AV美女一区二区三区| 精品无码一区二区三区在线| 国产精品99精品一区二区三区 | 亚洲乱码一区二区三区国产精品| 蜜臀AV无码一区二区三区| 国产人妖在线观看一区二区|