python爬蟲中使用Xpath方法定位a標籤中所有的子標籤的方法

老闆扔給了我一個陳年語料,讓我通過文章標題回原網址爬取一下對應的doi號,文章很好定位,但是在解析標題的時候遇到了問題,a標籤中混合了i、sub、sup標籤,在使用xpath時不能直接使用text方法獲取,所以在這裏記錄一下自己的解決方案。

(想不到,做完這個任務,我順便學會了希臘字母的讀音:^)

1 xpath定位

本篇博客以抓取我的主頁中的某條標題爲例。鼠標右鍵要爬的內容,點擊“檢查”,然後繼續右鍵定位到的內容,選擇copy,然後Copy Xpath,就可以獲得xpath表達式講真,作爲懶人,我喜歡這個定位,這樣就不用像beautifulSoup中那樣一點點的寫定位的元素了。具體操作如下圖所示。

圖1 獲取XPath操作

  獲得了XPath路徑之後,就可以在直接使用lxml包進行解析。操作樣例如下:

import requests
from lxml import html

etree = html.etree
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/79.0.3945.130 Safari/537.36',
    'Cookie': '寫自己的',
}

url = "https://blog.csdn.net/qq_33293040"  # 我的主頁
html = requests.get(url, headers=headers, timeout=20)  
xhtml = etree.HTML(html.content.decode("utf-8"))  # 解析網頁

node = xhtml.xpath('//*[@id="mainBox"]/main/div[2]/div[1]/h4/a')  # 填入剛纔獲得的xpath
print(node)  # 輸出結果:[<Element a at 0x2133a0b55c8>]

2 獲取子標籤——我的小技巧

1)要爬取的內容。span中的內容+純文本內容,源碼形式如下:

2)解決代碼:

def wash(node):
    res = ''
    for term in node.xpath("./node()[self::text() or self::span]"):
        # 技巧1:使用node()方法獲取其子標籤,如我們這裏是text()文本和span標籤,
        #       那麼使用"./node()[self::text() or self::span]"即可獲取;
        #       如果是i標籤就self::i,其他標籤就不贅述了。

        if str(term)[0] != '<':
            res += term  
            # 技巧2: 這裏卡了我好久,如何區分span和text,我這裏用了一個強制類型轉換,
            #        使其變成字符型,如果一開始是'<'說明不是text,不過,如果標題開頭
            #        本來就是'<',這個方法就涼了。

        elif term.tag == 'span':  # 使用tag屬性判斷是不是span標籤
            res += term.text  # 使用text屬性獲取文本內容

    res = res.strip()  # 只去掉首尾的空字符
    return res  # 返回拼好的文字


# 接上面第一節中的代碼
print(wash(node[0]))

# 輸出結果如下:
# 原創        動態規劃理解——以4道力扣題爲例

3)如果我想獲取子集的子集(孫子集)的內容呢?

解釋如下:

3 結語

因爲這次任務,我不再使用beautifulSoup,感覺Xpath太適合懶人使用了。他的優點是可以直接在瀏覽器中獲取他的xpath定位,並且直接複製就好,缺點是在多層嵌套的html下會需要對xpath進行修改才能使用(比如在ul下一堆的il標籤,返回的結果直接當list使用,但是習慣之後我還是覺得很方便)。

同時,我的任務中涉及文本清洗,需要大量的替換,爲了節省replace的次數,我想了一招,和大家分享一下:

def term_replace_set(term):
    # 用於清洗term  減少重複代碼工作
    replace_set = [
        ("’", "\'"),
        ("‘", "\'"),
        ('–', '-'),
        ('α', 'alpha'),
        ('β', 'beta'),
        ('κ', 'kappa'),
        ('ι', 'iota'),
        ('δ', 'delta'),
        ('λ', 'lambda'),
        ('γ', 'gamma'),
        ('η', 'eta'),
        ('≈', 'approximate'),
        ('Å', 'angstrom'),
        (' ', ' '),  # 替換奇怪的空字符
    ]
    for rule in replace_set:
        term = term.replace(rule[0], rule[1])  # 循環替代
    return term

(害 寫完之後有種自己是藝術家的錯覺,飄了飄了。另外,推薦一個學習希臘字母的網站,高中的時候都沒念全,竟現在學會了。)

我們學科真是好,只要有電腦,幹活少不了。告辭~

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章