網頁內容爬取:如何提取正文內容 BEAUTIFULSOUP的輸出


創建一個新網站,一開始沒有內容,通常需要抓取其他人的網頁內容,一般的操作步驟如下:

根據url下載網頁內容,針對每個網頁的html結構特征,利用正則表達式,或者其他的方式,做文本解析,提取出想要的正文。

為每個網頁寫特征分析這個還是太耗費開發的時間,我的思路是這樣的。

Python的BeautifulSoup包大家都知道吧,

import BeautifulSoup
soup = BeautifulSoup.BeautifulSoup(html)

利用這個包先把html里script,style給清理了:

[script.extract() for script in soup.findAll('script')] [style.extract() for style in soup.findAll('style')]

清理完成后,這個包有一個prettify()函數,把代碼格式給搞的標准一些:

soup.prettify()

然后用正則表達式,把所有的HTML標簽全部清理了:

reg1 = re.compile("<[^>]*>") content = reg1.sub('',soup.prettify())

剩下的都是純文本的文件了,通常是一行行的,把空白行給排除了,這樣就會知道總計有多少行,每行的字符數有多少,我用excel搞了一些每行字符數的統計,如下圖:

x坐標為行數,y坐標為該行的字符數

很明顯,會有一個峰值,81~91行就應該是這個網頁的正文部分。我只需要提取81~91行的文字就行了。

問題來了,照着這個思路,有什么好的算法能夠通過數據分析的方式統計出長文本的峰值在哪幾行?

BeautifulSoup不僅僅只是可以查找,定位和修改文檔內容,同樣也可以用一個好的 格式進行輸出顯示。BeautifulSoup可以處理不同類型的輸出:

  • 格式化的輸出
  • 非格式化的輸出

格式化輸出

 
BeautifulSoup中有內置的方法prettfy()來實現格式化輸出。比如:
  1. from bs4 import BeautifulSoup
  2. html_markup = “””<p class=”ecopyramid”>
  3. <ul id=”producers”>
  4. <li class=”producerlist”>
  5. <div class=”name”>plants</div>
  6. <div class=”number”>100000</div>
  7. </li>
  8. <li class=”producerlist”>
  9. <div class=”name”>algae</div>
  10. Output in Beautiful Soup
  11. <div class=”number”>100000</div>
  12. </li>
  13. </ul>”””
  14. soup = BeautifulSoup(html_markup,“lxml”)
  15. print(soup.prettify())

輸出:

 
 
prettify()可以用於BeautifulSoup對象也可以用於任何標簽對象。比如:
  1. producer_entry = soup.ul
  2. print(producer_entry.prettify())


非格式化輸出

 
可以使用str()和unicode()來進行非格式化輸出。
如果我們對BeautifulSoup對象和標簽對象使用str()方法,那么得到的就是一般的字符串輸出樣式。
我們也可以使用前篇講到的encode()方法來指定編碼格式的輸出。
對BeautifulSoup對象或標簽對象使用decode()方法來得到Unicode字符串。
 

BeautifulSoup中的輸出格式化

 
HTML實體編碼可以放進HTML文檔中用來表示特別的字符和標識。這些標識不存在於鍵盤上,這些HTML實體編碼只是當瀏覽器打開后才回看到效果。
在輸出方法中,只有這幾個HTML編碼有點例外。>和<和&三個符號。除此之外其他的特別標識都是被轉換成Unicode編碼當創建BeautifulSoup對象時,且當使用Prettify()方法或者其他方法輸出時,我們只能得到UTF-8格式的字符串。
 
html_markup = “””<html>
<body>& &amp; ampersand
¢ &cent; cent
© &copy; copyright
÷ &divide; divide
> &gt; greater than
</body>
</html>
 
輸出:

 

 
可以看到兩個沒有被轉換。BeautifulSoup自帶的輸出格式器來控制輸出。輸出格式器有以下幾種類型。
  • miimal
  • html
  • None
  • function
我們可以在輸出方法中傳遞上述輸出格式器參數,如prettify(),ncode(),decode()

miimal格式化

 
在這種格式化模式下,字符串被處理成一個有效的HTML代碼。這是默認的格式化輸出,此時輸出結果就和前面的一樣。不能轉換&amp;, &gt;和&lt;
 

Html格式化

 

這種格式化模式下,BeautifulSoup將會將Unicode字符轉換成HTML編碼形式。
print(soup.prettify(formatter=”html”))

輸出:
 
 

None格式化

 
這種情況下,BeautifulSoup不會改變字符串。這會導致產生一個非法的HTML代碼。
  1. print(soup.prettify(formatter=None))

輸出:

 
 

函數格式化

 
我們可以定義一個函數來處理字符串。比如去掉a字符。
 
  1. def remove_chara(markup):
  2.     return markup.replace(“a”,””)
  3. soup = BeautifulSoup(html_markup,“lxml”)
  4. print(soup.prettify(formatter=remove_chara))

輸出:

 
注意,其中字符a被替換掉了,但是注意的是&amp;, &gt;,和&lt;也被轉換了。
 

使用get_text()

 
從網頁中得到文本是常見的工作,BeautifulSoup提供了get_text()方法來達到目的。
 
如果我們只想得到BeautifulSoup對象的文本或標簽對象的文本內容,我們可以使用get_text()方法。比如:
  1. html_markup = “””<p class=”ecopyramid”>
  2. <ul id=”producers”>
  3. <li class=”producerlist”>
  4. <div class=”name”>plants</div>
  5. <div class=”number”>100000</div>
  6. </li>
  7. <li class=”producerlist”>
  8. <div class=”name”>algae</div>
  9. <div class=”number”>100000</div>
  10. </li>
  11. </ul>”””
  12. soup = BeautifulSoup(html_markup,“lxml”)
  13. print(soup.get_text())

輸出:

plants
100000
algae
100000
 
get_text()方法返回BeautifulSoup對象或標簽對象中的文本內容,其為一個Unicode字符串。但是get_text()有個問題是它同樣也會返回javascript代碼。

 

 
去掉javascript代碼的方法如下:
  1. [x.extract() for x in soup_packtpage.find_all(‘script’)]

這樣就會用處掉所有腳本元素。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM