iT邦幫忙

0

爬蟲scrapy抓取乾淨tag(裡面不要有其他tag或其他東西)的內容文字

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

是使用BeautifulSoup和scrapy來抓取

在抓取時遇到一個問題,就是目標tag底下還有其他tag或者其他東西

所以會抓出不只是新聞內容的文字

舉例來說,新聞內容都放在<div> class="caas-body" 底下的<p>裡面
https://ithelp.ithome.com.tw/upload/images/20210506/201194342yHZ4AiLNd.png

但是有的<p>裡面還會有其他tag
https://ithelp.ithome.com.tw/upload/images/20210506/20119434n36Wecr4Su.png
https://ithelp.ithome.com.tw/upload/images/20210506/20119434UXRaMTGbMt.png

或是出現其他非內容的東西
https://ithelp.ithome.com.tw/upload/images/20210506/20119434HxuzCscESu.png
https://ithelp.ithome.com.tw/upload/images/20210506/20119434Wj8vZ84D06.png

因為不是新聞內容,所以不需要抓出來

想請問有沒有方法可以只抓取乾淨的<p>(裡面除了文字沒有其他雜質)裡面的內容就好?

程式如下:

import scrapy
from bs4 import BeautifulSoup


class YahooCrawler(scrapy.Spider):
    name = 'yahoo'
    start_urls = (['https://tw.news.yahoo.com/%E7%94%B7%E5%AD%90%E6%BC%A2%E4%B9%8B%E7%B4%841-%E7%88%B6%E8%87%A8%E7%B5%82%E5%8F%AE%E5%9B%91-%E8%A6%81%E5%A0%85%E6%8C%81-%E6%B4%BB%E8%8F%A9%E8%96%A9-%E9%98%BF%E9%81%94%E5%93%A5-220000852.html'])

    def parse(self, response):
        res = BeautifulSoup(response.body)
        for content in res.select('div.caas-body p'):
            print(content.get_text())
還有個"**re**gular express正則表達式可以解決你的問題
了解,謝謝你~ 再找時間試試看XD

1 個回答

0
wrxue
iT邦研究生 3 級 ‧ 2021-05-06 08:46:24
最佳解答
for content in bsObj.select('div.caas-body p'):
    # 看底下有沒有其他 tag
    children = content.findChild()
    # 沒有的話才是想要的
    if children == None:
        print(content.get_text())

https://ithelp.ithome.com.tw/upload/images/20210506/201173578uRfKabwNI.png

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

太感謝你了,搞了好幾個小時都沒辦法解決...
剛好在我meeting前出現,真的感激不盡!
你這邊是不是把我原本的res換成bsObj?

這邊問一個蠢問題,小弟完全程式新手
大大的這個方法有想過,但是我的想法是
content.get_text()這個指令只要執行
就是把所有找到符合的tag內容都印出來
不會因為前面的條件而改變
雖然前面有if的條件,但也只是在這個條件下
把原本所有找到符合的tag內容都印出來
因為感覺content沒有被改變
請問這個觀念該怎麼調整?
for迴圈觀念不足? 還是if 或者是值被賦予另個值不了解

比如一個籃子裡面有的很多不同顏色的球
有個動作是(好比content.get_text()): 抓出所有印有A字樣的球
children = content.findChild() = 數一數球裡面還有沒有球
if children == None: = 若球裡面沒有球
print(content.get_text()) = 抓出所有印有A字樣的球
結果還是不會因為裡面有沒有球而改變...

wrxue iT邦研究生 3 級 ‧ 2021-05-06 09:58:25 檢舉
  1. 對,我忘記把 bsObj 改為你的 res 了
  2. 我覺得你的描述比較像是你不知道 for in 在做甚麼,content 是去迭代res.select('div.caas-body p')找到符合的tag。是「一個接一個」去迭代。所以for in裡面執行的程式碼,是「一個接一個」針對符合的tag去做判斷。就代表content是「某一個」符合的tag。
LIST = [x for x in range(1, 5)]
for i in LIST:
    if i % 2 :
        print(i) # 如果你說的對,這裡應該印出整個 LIST

謝謝,找時間仔細了解一下

我要發表回答

立即登入回答