首頁 > 後端開發 > Python教學 > 四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

發布: 2023-08-15 14:42:31
轉載
958 人瀏覽過


在使用Python本爬蟲採集資料時,一個很重要的操作就是如何從請求到的網頁中提取資料,而正確定位想要的資料又是第一步操作。

本文將比較幾種Python 爬蟲中比較常用的定位網頁元素的方式供大家學習

  1. 傳統BeautifulSoup 操作
  2. 基於BeautifulSoup 的CSS 選擇器(與PyQuery 類似)
  3. XPath
  4. 正規表示式

參考網頁是當網圖書暢銷總榜

http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1
登入後複製
四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

我們以取得第一頁 20 本書的書名為範例。先確定網站沒有設定反爬措施,是否能直接回傳待解析的內容:

import requests

url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text
print(response)
登入後複製
四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

#仔細檢查後發現需要的資料都在回傳內容中,說明不需要特別考慮反爬舉措

審查網頁元素後可以發現,書目資訊都包含在li 中,從屬於classbang_list clearfix bang_list_modeul四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

進一步檢視也可以發現書名在的對應位置,這是多種解析方法的重要基礎四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

1. 傳統BeautifulSoup 操作

經典的BeautifulSoup 方法借助from bs4 import BeautifulSoup,然後透過soup = BeautifulSoup(html, "Soup(html, "Soup# lxml") 將文字轉換為特定規範的結構,利用find

系列方法來解析,程式碼如下:
import requests
from bs4 import BeautifulSoup

url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text

def bs_for_parse(response):
    soup = BeautifulSoup(response, "lxml")
    li_list = soup.find('ul', class_='bang_list clearfix bang_list_mode').find_all('li') # 锁定ul后获取20个li
    for li in li_list:
        title = li.find('div', class_='name').find('a')['title'] # 逐个解析获取书名
        print(title)

if __name__ == '__main__':
    bs_for_parse(response)
登入後複製
四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

成功取得了20 個書名,有些書面顯得冗長可以透過正規或其他字串方法處理,本文不作詳細介紹###

2. 基于 BeautifulSoup 的 CSS 选择器

这种方法实际上就是 PyQuery 中 CSS 选择器在其他模块的迁移使用,用法是类似的。关于 CSS 选择器详细语法可以参考:http://www.w3school.com.cn/cssref/css_selectors.asp由于是基于 BeautifulSoup 所以导入的模块以及文本结构转换都是一致的:

import requests
from bs4 import BeautifulSoup

url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text
        
def css_for_parse(response):
    soup = BeautifulSoup(response, "lxml") 
    print(soup)

if __name__ == '__main__':
    css_for_parse(response)
登入後複製

然后就是通过 soup.select 辅以特定的 CSS 语法获取特定内容,基础依旧是对元素的认真审查分析:

import requests
from bs4 import BeautifulSoup
from lxml import html

url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text
        
def css_for_parse(response):
    soup = BeautifulSoup(response, "lxml")
    li_list = soup.select('ul.bang_list.clearfix.bang_list_mode > li')
    for li in li_list:
        title = li.select('div.name > a')[0]['title']
        print(title)

if __name__ == '__main__':
    css_for_parse(response)
登入後複製

3. XPath

XPath 即为 XML 路径语言,它是一种用来确定 XML 文档中某部分位置的计算机语言,如果使用 Chrome 浏览器建议安装 XPath Helper 插件,会大大提高写 XPath 的效率。

之前的爬虫文章基本都是基于 XPath,大家相对比较熟悉因此代码直接给出:

import requests
from lxml import html

url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text

def xpath_for_parse(response):
    selector = html.fromstring(response)
    books = selector.xpath("//ul[@class='bang_list clearfix bang_list_mode']/li")
    for book in books:
        title = book.xpath('div[@class="name"]/a/@title')[0]
        print(title)

if __name__ == '__main__':
    xpath_for_parse(response)
登入後複製

4. 正则表达式

如果对 HTML 语言不熟悉,那么之前的几种解析方法都会比较吃力。这里也提供一种万能解析大法:正则表达式,只需要关注文本本身有什么特殊构造文法,即可用特定规则获取相应内容。依赖的模块是 re

首先重新观察直接返回的内容中,需要的文字前后有什么特殊:

import requests
import re

url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text
print(response)
登入後複製
四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?

四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?观察几个数目相信就有答案了:<div class="name"><a href="http://product.dangdang.com/xxxxxxxx.html" target="_blank" title="xxxxxxx"> 书名就藏在上面的字符串中,蕴含的网址链接中末尾的数字会随着书名而改变。

分析到这里正则表达式就可以写出来了:

import requests
import re

url = &#39;http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1&#39;
response = requests.get(url).text

def re_for_parse(response):
    reg = &#39;<div class="name"><a href="http://product.dangdang.com/\d+.html" target="_blank" title="(.*?)">&#39;
    for title in re.findall(reg, response):
        print(title)

if __name__ == &#39;__main__&#39;:
    re_for_parse(response)
登入後複製

可以发现正则写法是最简单的,但是需要对于正则规则非常熟练。所谓正则大法好!

当然,不论哪种方法都有它所适用的场景,在真实操作中我们也需要在分析网页结构来判断如何高效的定位元素,最后附上本文介绍的四种方法的完整代码,大家可以自行操作一下来加深体会

import requests
from bs4 import BeautifulSoup
from lxml import html
import re

url = &#39;http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1&#39;
response = requests.get(url).text

def bs_for_parse(response):
    soup = BeautifulSoup(response, "lxml")
    li_list = soup.find(&#39;ul&#39;, class_=&#39;bang_list clearfix bang_list_mode&#39;).find_all(&#39;li&#39;)
    for li in li_list:
        title = li.find(&#39;div&#39;, class_=&#39;name&#39;).find(&#39;a&#39;)[&#39;title&#39;]
        print(title)

def css_for_parse(response):
    soup = BeautifulSoup(response, "lxml")
    li_list = soup.select(&#39;ul.bang_list.clearfix.bang_list_mode > li&#39;)
    for li in li_list:
        title = li.select(&#39;div.name > a&#39;)[0][&#39;title&#39;]
        print(title)

def xpath_for_parse(response):
    selector = html.fromstring(response)
    books = selector.xpath("//ul[@class=&#39;bang_list clearfix bang_list_mode&#39;]/li")
    for book in books:
        title = book.xpath(&#39;div[@class="name"]/a/@title&#39;)[0]
        print(title)

def re_for_parse(response):
    reg = &#39;<div class="name"><a href="http://product.dangdang.com/\d+.html" target="_blank" title="(.*?)">&#39;
    for title in re.findall(reg, response):
        print(title)

if __name__ == &#39;__main__&#39;:
    # bs_for_parse(response)
    # css_for_parse(response)
    # xpath_for_parse(response)
    re_for_parse(response)
登入後複製

以上是四種Python爬蟲常用的定位元素方法對比,你偏好哪一款?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:Python当打之年
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板