iT邦幫忙

0

爬蟲: 如何在同一個標籤內對<br>之間含特定文字的內容做排除?

目前在抓取ePrice新聞裡面完整的內容

是使用BeautifulSoup和requests來抓取

在抓取時遇到一個問題,就是目標tag中,底下的內容之間是用<br>隔開的

舉例來說,新聞內容都放在<dd class="normal first-thread">底下
<div class="user-comment-block">裡面
https://ithelp.ithome.com.tw/upload/images/20210608/20119434M4R57J56Vx.png

但是之間都是用<br>來做換行
https://ithelp.ithome.com.tw/upload/images/20210608/20119434wxkAghylXn.png

因此沒辦法用排除特定標籤或文字的方法來對裡面的內容做處理

由於也會出現圖片註解或特定文字需要排除

圖片註解:
https://ithelp.ithome.com.tw/upload/images/20210608/201194342jSKLugT7S.png
https://ithelp.ithome.com.tw/upload/images/20210608/20119434RNP1BwlUUq.png

特定文字:
https://ithelp.ithome.com.tw/upload/images/20210608/20119434ahGZDrdRMK.png
https://ithelp.ithome.com.tw/upload/images/20210608/20119434ymo6DiXGi1.png

想請問有沒有方法可以將同一個標籤底下用<br>隔開

且含有特定文字(EX: ▲、引用來源)的內容排除?

程式碼:

import json
from bs4 import BeautifulSoup
import requests


class crawlerClass:
    def __init__(self):
        print("init")
        
    def EpriceCrawler(self, url):
        response = requests.get(url, verify=False)
        soup = BeautifulSoup(response.text, "html.parser")

        section = ""
        for tag in soup.select('dd.normal.first-thread div.user-comment-block'):
            if tag.get_text() != "":
                section += tag.get_text()
                section = section.strip()
                section += "\n\n"
        article = {'status': 0, 'content': section}
        return json.dumps(article)
        
        
if __name__ == "__main__":
    crawler = crawlerClass()
    # ==== Eprice ====
    url = "https://www.eprice.com.tw/mobile/talk/4693/5644362/1/"
    epriceJsonStr = crawler.EpriceCrawler(url)
    epriceContent = json.loads(epriceJsonStr, encoding="utf-8")
    print("status:"+str(epriceContent['status']))
    print(epriceContent['content'])

PS: 有時候執行結果會出現亂碼,可先忽略不管
https://ithelp.ithome.com.tw/upload/images/20210608/20119434z7HGFQ3Csc.png

2 個回答

0
wrxue
iT邦研究生 3 級 ‧ 2021-06-09 08:56:02
最佳解答

soup.select('dd.normal.first-thread div.user-comment-block')拿到的是整個文章了,所以你用 tag.get_text() != ""一定會True,所以要先把文章分為一行一行的,然後再去判斷


    def EpriceCrawler(self, url):
    ...
    ...
        section = ""
        excepts = ['▲', '引用來源']
        for tag in soup.select('dd.normal.first-thread div.user-comment-block'):
            # 內容分行
            contents = tag.get_text().splitlines()
            # 跌代每一行
            for line in contents:
                # 各別去判斷每一行的情況
                if line == "":
                    continue
                for e in excepts:
                    if e in line:
                        break
                else:
                    section += line
                    section = section.strip()
                    section += "\n\n"
    ...
    ...

你的想法把在成對的<br>tag內且符合某些條件的內容刪掉,這是不太合理的判斷方式,因為<br>本來就不成對,無法得知誰跟誰是一對。
https://ithelp.ithome.com.tw/upload/images/20210609/20117357Af3G04TqQq.png

it works, thx~
你誤解我了,我的意思是把<br>間的內容符合條件的刪掉就好
不成對的概念我還是有啦

0
japhenchen
iT邦大師 1 級 ‧ 2021-06-09 08:28:41

照我幫你改的那一篇<BR>斷行那篇,你可以再引用re.sub做特定字串代換

import re


#................. 你的程式
                section += tag.get_text(separator="\n")
                section = section.strip()
                section = re.sub(r"^\s*引用來源[::]*.*$","",section)
                section += "\n\n"


看更多先前的回應...收起先前的回應...

用正則表達式做特定字串代換真的很好用

這樣就可以

section = re.sub(r"^\s*引用來源[::]*.*$","",section)

好像不行,我的輸出結果還是有出現
https://ithelp.ithome.com.tw/upload/images/20210609/20119434vc2lAXDSKl.png

                section += tag.get_text()
                section = section.strip()
                section = re.sub(r"^\s*引用來源[::]*.*$", "", section)
                section += "\n\n"

簡化成下列試試

section = re.sub(r"\s*引用來源.*\n", "", section)

還是不行耶

是我眼拙沒見到雙引號?

section = re.sub(r"\"*.*引用來源.*\"*\n*", "", section)

我要發表回答

立即登入回答