日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在了解爬蟲基礎、請求庫和正則匹配庫以及一個具體豆瓣電影爬蟲實例之后,可能大家還對超長的正則表達式記憶猶新,設想如果想要匹配的條目更加多那表達式長度將會更加恐怖,這顯然不是我們想要的,因此本文介紹的解析庫可以幫助我們更加輕松地提取到特定信息。

一文弄清Python網絡爬蟲解析庫!內含多個實例講解

 

一、Xpath庫

1.庫簡介

XPath(XML Path Language)即XML 路徑語言,它是一門在XML文檔中查找信息的語言,但它同樣適用于html 文檔的搜索。所以在做爬蟲時,我們完全可以使用XPath 來做相應的信息抽取。

2.入門測試

需要導入lxml庫(若未安裝推薦用pip install lxml安裝即可),然后使用下面代碼進行簡單測試:

from lxml import etree
text = '''<html><body><div>
    <ul>
        <li class="item-0"><a href="link1.html">first</a></li>
        <li class="item-1"><a href="link2.html">second</a>
        <li class="item-2"><a href="link3.html">third</a></li>
        <li class="item-3"><a href="link4.html">fourth</a></li>
    </ul>
</div>'''
html = etree.HTML(text)
result = etree.tostring(html)
print(result.decode('utf-8'))

結果如下:可以看到,etree模塊不僅將缺少的標簽閉合了,而且還加上了html、body節點。

<html><body><div>
    <ul>
        <li class="item-0"><a href="link1.html">first</a></li>
        <li class="item-1"><a href="link2.html">second</a>
        </li><li class="item-2"><a href="link3.html">third</a></li>
        <li class="item-3"><a href="link4.html">fourth</a></li>
    </ul>
</div></body></html>

3.基本方法

xpath的常用規則及基本方法如下:

一文弄清Python網絡爬蟲解析庫!內含多個實例講解

 

  • 初始化html

上文中的入門測試即為初始化html。其中etree.parse()是初始化html構造一個XPath解析對象;etree.tostring()是修復html文件中代碼,把缺的頭或尾節點補齊;result.deode('utf-8')修復后的HTML代碼是字節類型,轉化成字符串。

  • 獲取所有節點
print(html.xpath('//*')) # 獲取所有的節點
print(html.xpath('//li')) # 獲取所有li節點
  • 子節點、子孫節點
print(html.xpath('//li/a')) # 所有li下是所有直接a子節點
print(html.xpath('//ul//a')) # 所有ul下的子孫a節點
  • 父節點
# 找到所有a節點中href為links.html的父節點的class值
#  ..  來實現查找父節點
print(html.xpath('//a[@href="link1.html"]/../@class'))
  • 屬性匹配
# 找到class值為item-0是節點
print(html.xpath('//li[@class="item-0"]'))
  • 文本獲取
# 匹配到class值為item-0節點中的a標簽中的文本
print(html.xpath('//li[@class="item-0"]/a/text()'))
  • 屬性獲取
print(html.xpath('//li/a/@href'))  # 找到li下a中的href屬性值
  • 屬性多值匹配
#只要節點屬性class中包含item就能匹配出來
print(html.xpath('//li[contains(@class,"item")]/a/text()'))
一文弄清Python網絡爬蟲解析庫!內含多個實例講解

 

二、BeautifulSoup庫

1.庫簡介

BeautifulSoup4和 lxml 一樣,Beautiful Soup 也是一個HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 數據。BeautifulSoup支持Python/ target=_blank class=infotextkey>Python標準庫中的HTML解析器,還支持一些第三方的解析器,如果我們不安裝它,則 Python 會使用 Python默認的解析器,lxml 解析器更加強大,速度更快,推薦使用lxml 解析器。

一文弄清Python網絡爬蟲解析庫!內含多個實例講解

 

2.入門測試

假設有這樣一個Html(即從百度網頁源代碼截取一段),具體內容如下:

html = '''
<!DOCTYPE html>
<html>
<head>
    <meta content="text/html;charset=utf-8" http-equiv="content-type" />
    <meta content="IE=Edge" http-equiv="X-UA-Compatible" />
    <meta content="always" name="referrer" />
    <link href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css" />
    <title>百度一下,你就知道 </title>
</head>
<body link="#0000cc">
  <div id="wrApper">
    <div id="head">
        <div class="head_wrapper">
          <div id="u1">
            <a class="mnav" href="http://news.baidu.com" name="tj_trnews">新聞 </a>
            <a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
            <a class="mnav" href="http://map.baidu.com" name="tj_trmap">地圖 </a>
            <a class="mnav" href="http://v.baidu.com" name="tj_trvideo">視頻 </a>
            <a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">貼吧 </a>
            <a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多產品 </a>
          </div>
        </div>
    </div>
  </div>
</body>
</html>'''

如果將字符串單獨保存為html文件,則使用谷歌瀏覽器打開后即為:

 

一文弄清Python網絡爬蟲解析庫!內含多個實例講解

 

通過導入bs4庫中的BeautifulSoup子類可以輸入以下命令觀察輸出:

from bs4 import BeautifulSoup 
bs = BeautifulSoup(html,"html.parser") # 縮進格式
print(bs.prettify()) # 獲取title標簽的所有內容
    print(bs.title) # 獲取title標簽的名稱
print(bs.title.name) # 獲取title標簽的文本內容
print(bs.title.string) # 獲取head標簽的所有內容
print(bs.head) # 獲取第一個div標簽中的所有內容
print(bs.div) # 獲取第一個div標簽的id的值
print(bs.div["id"]) # 獲取第一個a標簽中的所有內容
print(bs.a) # 獲取所有的a標簽中的所有內容
print(bs.find_all("a")) # 獲取id="u1"
print(bs.find(id="u1")) # 獲取所有的a標簽,并遍歷打印a標簽中的href的值
for item in bs.find_all("a"): 
    print(item.get("href")) # 獲取所有的a標簽,并遍歷打印a標簽的文本值
for item in bs.find_all("a"): 
    print(item.get_text())

3.基本方法

BeautifulSoup4將復雜HTML文檔轉換成一個復雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種:

  • Tag:Tag通俗點講就是HTML中的一個個標簽,我們可以利用 soup 加標簽名輕松地獲取這些標簽的內容,這些對象的類型是bs4.element.Tag。但是注意,它查找的是在所有內容中的第一個符合要求的標簽。
# [document] #bs 對象本身比較特殊,它的 name 即為 [document]
print(bs.name) 
# head #對于其他內部標簽,輸出的值便為標簽本身的名稱
print(bs.head.name) 
# 在這里,我們把 a 標簽的所有屬性打印輸出了出來,得到的類型是一個字典。
print(bs.a.attrs) 
#還可以利用get方法,傳入屬性的名稱,二者是等價的
print(bs.a['class']) # 等價 bs.a.get('class')
# 可以對這些屬性和內容等等進行修改
bs.a['class'] = "newClass"
print(bs.a) 
# 還可以對這個屬性進行刪除
del bs.a['class'] 
print(bs.a)
  • NavigableString:既然我們已經得到了標簽的內容,那么問題來了,我們要想獲取標簽內部的文字怎么辦呢?很簡單,用 .string 即可,例如:
print(bs.title.string) 
print(type(bs.title.string))
  • BeautifulSoup:BeautifulSoup對象表示的是一個文檔的內容。大部分時候,可以把它當作 Tag 對象,是一個特殊的 Tag,我們可以分別獲取它的類型,名稱,以及屬性,例如:
print(type(bs.name)) 
print(bs.name) 
print(bs.attrs)
  • Comment:Comment 對象是一個特殊類型的 NavigableString 對象,其輸出的內容不包括注釋符號。
print(bs.a)
# 此時不能出現空格和換行符,a標簽如下:
# <a class="mnav" href="http://news.baidu.com" name="tj_trnews"><!--新聞--></a>
print(bs.a.string) # 新聞
print(type(bs.a.string)) # <class 'bs4.element.Comment'

接下來具體講解BeautifulSoup的使用方法。我們可以通過BeautifulSoup遍歷文檔樹:

  • .contents:獲取Tag的所有子節點,返回一個list
# tag的.content 屬性可以將tag的子節點以列表的方式輸出
print(bs.head.contents)
# 用列表索引來獲取它的某一個元素
print(bs.head.contents[1])
  • .children:獲取Tag的所有子節點,返回一個生成器
for child in  bs.body.children:
    print(child)
  • .descendants:獲取Tag的所有子孫節點
  • .strings:如果Tag包含多個字符串,即在子孫節點中有內容,可以用此獲取,而后進行遍歷
  • .stripped_strings:與strings用法一致,只不過可以去除掉那些多余的空白內容
  • .parent:獲取Tag的父節點
  • .parents:遞歸得到父輩元素的所有節點,返回一個生成器
  • .previous_sibling:獲取當前Tag的上一個節點,屬性通常是字符串或空白,真實結果是當前標簽與上一個標簽之間的頓號和換行符
  • .next_sibling:獲取當前Tag的下一個節點,屬性通常是字符串或空白,真是結果是當前標簽與下一個標簽之間的頓號與換行符
  • .previous_siblings:獲取當前Tag的上面所有的兄弟節點,返回一個生成器
  • .next_siblings:獲取當前Tag的下面所有的兄弟節點,返回一個生成器
  • .previous_element:獲取解析過程中上一個被解析的對象(字符串或tag),可能與previous_sibling相同,但通常是不一樣的
  • .next_element:獲取解析過程中下一個被解析的對象(字符串或tag),可能與next_sibling相同,但通常是不一樣的
  • .previous_elements:返回一個生成器,可以向前訪問文檔的解析內容
  • .next_elements:返回一個生成器,可以向后訪問文檔的解析內容
  • .has_attr:判斷Tag是否包含屬性

也可以通過BeautifulSoup進行搜索文檔樹:

  • find_all(name, attrs, recursive, text, **kwargs)

在上面的示例中我們簡單介紹了find_all的使用,接下來介紹一下find_all的更多用法-過濾器。這些過濾器貫穿整個搜索API,過濾器可以被用在tag的name中,節點的屬性等。

from bs4 import BeautifulSoup 
import re 
bs = BeautifulSoup(html,"html.parser") 
t_list = bs.find_all(re.compile("a")) 
for item in t_list: 
   print(item)
  • find()

find()將返回符合條件的第一個Tag,有時我們只需要或一個Tag時,我們就可以用到find()方法了。當然了,也可以使用find_all()方法,傳入一個limit=1,然后再取出第一個值也是可以的,不過未免繁瑣。

from bs4 import BeautifulSoup 
import re 
# 返回只有一個結果的列表
t_list = bs.find_all("title",limit=1) 
print(t_list) 
# 返回唯一值
t = bs.find("title") 
print(t) 
# 如果沒有找到,則返回None
t = bs.find("abc") 
print(t)
  • CSS選擇器

BeautifulSoup支持發部分的CSS選擇器,在Tag獲取BeautifulSoup對象的.select()方法中傳入字符串參數,即可使用CSS選擇器的語法找到Tag:

  • 通過標簽名查找
print(bs.select('title'))
print(bs.select('a'))
  • 通過類名查找
print(bs.select('.mnav'))
  • 通過id查找
print(bs.select('#u1'))
  • 組合查找
print(bs.select('div .bri'))
  • 屬性查找
print(bs.select('a[class="bri"]'))
print(bs.select('a[href="http://tieba.baidu.com"]'))
  • 直接子標簽查找
t_list = bs.select("head > title")
print(t_list)
  • 兄弟節點標簽查找
t_list = bs.select(".mnav ~ .bri")
print(t_list)
  • 獲取內容
t_list = bs.select("title")
print(bs.select('title')[0].get_text())
一文弄清Python網絡爬蟲解析庫!內含多個實例講解

 

三、pyquery庫

1.庫簡介

如果覺得Xpath有些難懂,BeautifulSoup有些難記,那pyquery一定適合你。pyquery 可讓你用 jQuery 的語法來對 xml 進行操作。這和 jQuery 十分類似。如果利用 lxml,pyquery 對 xml 和 html 的處理將更快。這個庫不是一個可以和 JAVAScript交互的代碼庫,它只是非常像 jQuery API 而已。

2.入門測試

# html為上文BeautifulSoup測試實例
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('title').text()) # '標題'
print(doc('div').filter('.head_wrapper').text()) # '文字1'
print(doc('a[name=tj_trnews]').text()) # 同上,只是這種方法支持除了id和class之外的屬性篩選
print(doc('div').filter('#u1').find('a').text()) # '列表1第1項 列表1第2項'
print(doc('div#u1 a').text()) # 簡化形式
print(doc('div#u1 > a').text()) # 節點之間用>連接也可以,但是加>只能查找子元素,空格子孫元素

3.基本方法

  • 初始化
# 字符串初始化:
from pyquery import PyQuery as pq
doc=pq(html)
print(doc('li'))
# URL初始化
doc=pq(url="https://ww.baidu.com")
print(doc)
a = open('test.html','r',encoding='utf8')
doc=pq(a.read())
print(doc)
  • 基本css選擇器
# id 為container,class為list下的所有li
print(doc('.head_wrapper #u1 a'))
  • 查找節點
# .find():查找所有子孫節點
items = doc('#u1')
print(items.find('a'))
# .children():查找子節點
items=doc('#u1')
print(items.children('.mnav'))
# 父節點
doc=pq(html)
items=doc('.mnav')
print(items.parent())
print(items.parents())
# 兄弟節點
doc=pq(html)
li=doc('.mnav')
print(li.siblings('.bri'))
  • 遍歷
# 用items()函數生成列表生成器進行遍歷
doc=pq(html)
lis=doc('a').items()
for li in lis:
  print(li)
  • 獲取信息
# 獲取屬性
a=doc('.head_wrapper #u1 .bri')
# attr只會輸出第一個a節點屬性,要用items()遍歷
print(a.attr('href'))
# 獲取文本
# .text()
a=doc('.head_wrapper #u1 .bri')
# text()函數會輸出所有的li文本內容
print(a.text())
# .html()
li=doc('a')
# html()只會輸出第一個li節點內的HTML文本
print(li.html())
  • 節點操作
# removeClass addClass
a=doc('.head_wrapper #u1 .bri')
print(a)
a.removeClass('bri')  # 移除active的class
print(a)
a.addClass('bri')   # 增加active的class
print(a)
# attr text html
a.attr('name','link')    # 增加屬性name=link
a.text('changed item')   # 改變文本 changed item
a.html('<span>changed item </span>')   # 改變HTML
print(a)
 # remove()
u1=doc('#u1')
# 刪除wrap中p節點
u1.find('a').remove()
print(u1.text())

Python有關Xpath、BeautifulSoup、pyquery三大解析庫的基本使用方法介紹至此結束

分享到:
標簽:爬蟲 網絡 Python
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定