一起學爬蟲——PyQuery常用用法總結

来源:https://www.cnblogs.com/airnew/archive/2018/12/03/10056551.html
-Advertisement-
Play Games

什麼是PyQuery PyQuery是一個類似於jQuery的解析網頁工具,使用lxml操作xml和html文檔,它的語法和jQuery很像。和XPATH,Beautiful Soup比起來,PyQuery更加靈活,提供增加節點的class信息,移除某個節點,提取文本信息等功能。 初始化PyQuer ...


什麼是PyQuery

PyQuery是一個類似於jQuery的解析網頁工具,使用lxml操作xml和html文檔,它的語法和jQuery很像。和XPATH,Beautiful Soup比起來,PyQuery更加靈活,提供增加節點的class信息,移除某個節點,提取文本信息等功能。

初始化PyQuery對象

html文檔的所有操作都需要PyQuery對象來完成,初始化PyQuery對象主要有三種方式,分別是通過網址、字元串和文件名創建。

方式一:通過網址初始化PyQyery對象
先看一段代碼:

from pyquery import PyQuery as pq

s = '<html><title>PyQuery用法總結<title></html>'
doc = pq(s)
print(doc('title'))

運行結果:

<title>PyQuery用法總結</title>

首先要import PyQuery類,然後將字元串傳遞給PyQuery類,這樣就生成了一個PyQuery對象,通過該對象就可以訪問字元串中的title節點。
PyQuery還會將殘缺的html文檔補全。看下麵的代碼:

from pyquery import PyQuery as pq

s = '<html><title>PyQuery用法總結</title>'
doc = pq(s)
print(doc('html'))

運行的結果:

<html><head><title>PyQuery用法總結</title></head></html>

可以我們的字元串的html節點是沒有閉合的,並且缺少head節點。初始化PyQuery對象之後,會把html文檔補全,並且自動加上head節點。

方式二:URL網址初始化PyQyery對象
將要解析的URL網址當做參數傳遞給PyQuery類:

from pyquery import PyQuery as pq

url = 'http://www.bigdata17.com'
doc = pq(url=url,encoding='utf-8')
print(doc('title'))

運行結果:

<title>Home - Summer哥的自留地</title>

方式三:通過文件初始化PyQyery對象
這個方式也比較常用,很多時候我們會將網站爬取下來然後保存在本地磁碟:

from pyquery import PyQuery as pq

doc = pq(filename='test_pyquery.html',encoding='utf-8')
print(doc('title'))

訪問節點屬性:
使用attr()方法訪問節點的屬性:

from pyquery import PyQuery as pq
li = pq('<li id="test1" class="test1"></li><li id="test2" class="test2"></li>')('li')
print(li.attr("id"))

運行結果:

test1

上面的代碼中有兩個id不同的li節點,但是attr()方法只取第一個li節點的id屬性值,而不取第二個,我們把上面的代碼修改下,把第一個li節點的id屬性去掉,attr方法是否只取第一個複合條件節點的屬性值:

from pyquery import PyQuery as pq
li = pq('<li class="test1"></li><li id="test2" class="test2"></li>')('li')
print(li.attr("id"))

運行結果:

None

第一個li節點沒有id屬性,因此返回結果為None,所以可見,attr()方法返回的是第一個節點的屬性值。

那要取多個li節點的屬性值,要怎麼做呢?這就要結合items()方法來實現。items()方法是返回的節點的生成器generator object PyQuery.items

from pyquery import PyQuery as pq
li = pq('<li id="test1" class="test1"></li><li id="test2" class="test2"></li>')('li')
print(li.items())
for item in li.items():
    print(item.attr("id"))

運行結果:

<generator object PyQuery.items at 0x0000027F26082728>
test1
test2

動態添加節點屬性
PyQuery有很多方法動態添加節點的屬性,我們挑選幾個比較常用的方法介紹個大伙。
addClass(),動態添加節點class屬性:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.addClass("addClass")
print(li)

運行結果:
<li id="test1" class="test1 addClass"/>
可見li節點的calss屬性值有test1變為test1 addclass。

addClass()方法只能動態添加節點class屬性的值,能不能動態添加其他屬性呢?答案是當然可以,attr()方法就可以實現:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.attr("name","li name")
print(li)
li.attr("type","li")
print(li)
print(li.attr("type"))

運行結果:

<li id="test1" class="test1" name="li name"/>
<li id="test1" class="test1" name="li name" type="li"/>
li

上面的代碼一共執行了3次attr()方法,執行第一次attr()方法時,有兩個參數,分別是name和li name。這是給li節點添加name屬性及屬性值。執行第二次attr()方法也有兩個參數,分別是type和li,這是給li幾點添加type屬性及type屬性值。執行第三次方法attr()方法只有一個type參數,根據前面介紹的attr()方法的用法可知,是獲取li節點type屬性的值。

小結: attr()方法只有一個參數時,是獲取節點的屬性值,有兩個參數時,是給節點添加屬性及屬性值,第一個參數時屬性,第二個參數時屬性值。

removeClass(),動態移除節點的class屬性:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.removeClass("test1")
print(li)

運行結果:
<li id="test1" class=""/>
將class節點的屬性值有test1變為“”。

動態添加/修改文本值
PyQuery支持動態給節點添加文本值:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.html("use html() dynamic add text")
print(li)
li.text("use text() dynamic add text")
print(li)

運行結果:

<li id="test1" class="test1">use html() dynamic add text</li>
<li id="test1" class="test1">use text() dynamic add text</li>

可見使用html()和text()方法都可以動態的給節點添加或修改節點的文本值。

獲取節點文本值
PyQuery提供text()和html()方法獲取節點的文本屬性值:

from pyquery import PyQuery as pq
html = '<li id = "test_id">li text value</li>'
li = pq(html)('li')
print(li.text())
print(li.html())

運行結果:

li text value
li text value

小結: html()和text()如果沒參數,則是獲取屬性的文本值,如果有參數,則是改變或者添加節點的屬性值。

移除節點:
remove()方法可以動態移除節點:

from pyquery import PyQuery as pq
html = '''
<ul>
hello I am ul tag
<li>hello I am li tag</li>
</ul>
'''
ul = pq(html)('ul')
print(ul.text())
print('執行remove()移除節點')
ul.find('li').remove()
print(ul.text())

運行結果:

hello I am ul tag
hello I am li tag
執行remove()移除節點
hello I am ul tag

上述代碼的ul節點中有個li節點,執行ul.text()方法會返回包括li節點的文本信息,如果我們不想返回li節點的文本信息,僅僅只需要ul節點的文本信息“hell I am ul tag”,要怎麼做呢?這時候remove()方法就派上用場了,它刪除掉ul節點內的li節點。

查找節點
PyQuery支持使用css的.和#來查找節點:

from pyquery import PyQuery as pq
html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag li'))

運行結果:

<li>hello I am li tag</li>
<li>hello I am li tag too</li>

上述代碼是通過.div_tag獲取class為div_tag的節點,然後通過#ul_tag獲取id為ul_tag的節點,最後返回所有的li節點。

find()方法查找節點:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag').find("li"))

運行結果:

<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>

可見find("li")是把所有li節點及子節點都查找出來。

還有一個children()方法,是獲取當前節點的所有子節點。該方法可以傳入css選擇器:children('.ul_tag')。

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag').find("li"))

運行結果:

<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>

使用parent()方法獲取當前節點的父親節點:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag li').parent())

運行結果:

<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>

上述代碼通過.div_tag #ul_tag li css選擇器定位到li節點,然後調用parent()方法獲取li節點的父節點ul。

parents()返回當前節點的所有祖宗節點:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag li').parents())

運行結果:

<html><body><div class="div_tag">
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>
</div>
</body></html><body><div class="div_tag">
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>
</div>
</body><div class="div_tag">
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>
</div>
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>

上面代碼返回li節點的所有祖宗節點:html,body,div,ul。

siblings()方法返回當前節點的兄弟節點:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li class="li_class1">hello I am li tag<a>www.bigdata17.com</li>
<li class="li_class2">hello I am li tag too</li>
<li class="li_class3">hello I am the third li tag</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag .li_class1').siblings())

運行結果:

<li class="li_class2">hello I am li tag too</li>
<li class="li_class3">hello I am the third li tag</li>

使用.div_tag #ul_tag .li_class1 CSS節點選擇器獲取到class為liclassq1的li節點,就是第一個li節點,然後調用siblings()方法獲取到子節點,分別是
第二和第三個li節點。

sibligs()還支持傳入css選擇器篩選符合條件的li節點:

print(doc('.div_tag #ul_tag .li_class1').siblings('.li_class3'))

運行結果:

<li class="li_class3">hello I am the third li tag</li>

總結:本文講述瞭如何使用PyQuery獲取網頁節點,節點的文本信息,改變節點屬性,刪除節點屬性,增加節點屬性等知識點。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.關於數據綁定的問題 小程式更新data後只是把數據的值更新,不會刷新頁面,比如滑動的列表不會回到頂部,導致使用swiper有個小bug: 就是swiper的數據是後臺請求的,可通過切換tab標簽動態獲取,如果在切換之前swiper處在第三張或者更多(比將要點擊的tab下的swiper多),那切換 ...
  • 聲明 本系列文章內容全部梳理自以下幾個來源: 《JavaScript權威指南》 "MDN web docs" "Github:smyhvae/web" "Github:goddyZhao/Translation/JavaScript" 作為一個前端小白,入門跟著這幾個來源學習,感謝作者的分享,在其基 ...
  • 當let聲明一個變數的時候它使用的詞法作用域或者是塊作用域。塊作用域指的就是他們包含的塊以外的不能訪問。 const聲明:是let聲明有相同的作用域規則,但是它被賦值後不能再被改變。類似於java的final TypeScript 可以用 `` 來聲明多行字元串,編譯之後js文件換行的地方會加上\n ...
  • 1. 動畫 (1) Css樣式提供了運動 過渡的屬性transition 從一種情況到另一種情況叫過渡 Transition:attr time linear delay; Attr 是變化的屬性 Time 是花費的時間 Linear 變化的速度 Delay 是延遲 複習background:url ...
  • 一. for迴圈和while迴圈中的else代表什麼意思? 二. break, continue, pass, return和exit分別代表什麼意思? 三. 寫迴圈代碼時, for 和 while該如何選擇, 以及有什麼註意事項? 四. 代碼實現: 接收用戶輸入的兩個數值a和b, 使用迴圈計算出a ...
  • #關鍵:array_rand() 函數返回數組中的隨機鍵名,或者如果您規定函數返回不只一個鍵名,則返回包含隨機鍵名的數組。#思路:先使用array_rand()隨機取出所需數量鍵名,然後將這些鍵名指向的值重新組合為數組 1 /** 2 * 數組中取出隨機取出指定數量子值集 3 * @param $a ...
  • 一、php中常見的危險函數和審計要點 危險函數(功能過於強大) 參數是否外部可控,有沒有正確的過濾。 PHP獲取外界傳入參數是通過下麵幾個全局函數的形式,所以審計參數傳入經常要和下麵幾個變數打交道 PHP中危險函數有五大特性: 參數是否可控 執行任意代碼函數 1)把傳入的字元串直接當成php代碼直接 ...
  • 題意 "題目鏈接" Sol 打出暴力不難發現時間複雜度的瓶頸在於求$\sum_{i = 1}^n i^k$ 老祖宗告訴我們,這東西是個$k$次多項式,插一插就行了 cpp // luogu judger enable o2 include using namespace std; const int ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...