在某些情况下,Web Scraping 新闻文章会返回空正文

问题描述

我只是想从 El Pais 网站存档中抓取一些文章。我从每篇文章中选取:标题主题标签文章正文。每篇文章的 HTML 结构都是相同的,并且所有标题主题标签的脚本都是成功的,但是对于某些文章,它根本不会抓取正文。下面我添加了我的代码、完整工作文章链接以及一些返回空正文的链接。你知道如何解决吗? 空体文章不定期出现,所以有时可以连续出现3个空文章,然后5个成功文章,1个空文章,3个成功。

工作文章 第1条 https://elpais.com/diario/1990/01/17/economia/632530813_850215.html 第2条 https://elpais.com/diario/1990/01/07/internacional/631666806_850215.html 第三条 https://elpais.com/diario/1990/01/05/deportes/631494011_850215.html

没有正文的文章 第四条 https://elpais.com/diario/1990/01/23/madrid/633097458_850215.html 第五条 https://elpais.com/diario/1990/01/30/economia/633654016_850215.html 第六条 https://elpais.com/diario/1990/01/03/espana/631321213_850215.html

    from bs4 import BeautifulSoup
    import requests
    #place for the url of the article to be scraped
    URL = some_url_of_article_above
    #print(URL)
    page = requests.get(URL)
    soup = BeautifulSoup(page.content,"html.parser")
    bodydiv = soup.find("div",id="ctn_article_body")
    artbody = bodydiv.find_all("p",class_="")
    tagdiv = soup.find("div",id="mod_archivado")
    hashtags= tagdiv.find_all("li",class_="w_i | capitalize flex align_items_center")
    titlediv = soup.find("div",id="article_header")
    title = titlediv.find("h1")
    #print title of the article
    print(title.text)
    #print body of the article
    arttext = ""
    for par in artbody:
        arttext += str(par.text)
    print(arttext)
    #hastags
    tagstring = ""
    for hashtag in hashtags:
        tagstring += hashtag.text
        tagstring += ","
    print(tagstring)

预先感谢您的帮助!

解决方法

问题在于 <div class="a_b article_body | color_gray_dark" id="ctn_article_body"> 元素内部有一个损坏或不完整的 <b> 标签。从 html 页面查看此代码片段:

<div id="ctn_article_body" class="a_b article_body | color_gray_dark"><p class=""></b>La Asociación Ecologista de Defensa dela Naturaleza (AEDENAT) ha denunciado que las obras de la carretera que cruza la Universidad Complutense desde la carretera de La Coruña hasta Cuatro Caminos se están realizando "sin permisos de ningún tipo" y suponen "la destrucción de zonas de pinar en las cercanías del edificio de Filosofia B".</p>

就在第一个 <p></p> 标签之后,有一个没有 </b> 标签的 <b>。这就是“html.parser”失败的原因。

使用此文本,

from bs4 import BeautifulSoup

text = """<div id="ctn_article_body" class="a_b article_body | color_gray_dark"><p class=""></b>La Asociación Ecologista de Defensa de la Naturaleza (AEDENAT) ha denunciado que las obras de la carretera que cruza la Universidad Complutense desde la carretera de La Coruña hasta Cuatro Caminos se están realizando "sin permisos de ningún tipo" y suponen "la destrucción de zonas de pinar en las cercanías del edificio de Filosofia B".</p><div id="elpais_gpt-INTEXT" style="width: 0px; height: 0px; display: none;"></div><p class="">Por su parte,José Luis Garro,tercer teniente de alcalde,ha declarado a EL PAÍS: "Tenemos una autorización provisional del rector de la Universidad Complutense. Toda esa zona,además,está pendiente de un plan especial de reforma interior (PERI). Ésta es sólo una solución provisional".</p><p class="">Según Garro,el trazado de la carretera "ha tenido que dar varias vueltas para no tocar las masas arbóreas",aunque reconoce que se ha hecho "en algunos casos",si bien causando "un daño mínimo".</p><p class="footnote">* Este artículo apareció en la edición impresa del lunes,22 de enero de 1990.</p></div>"""

soup = BeautifulSoup(text,"html.parser")
print(soup.find("div"))

输出:

<div class="a_b article_body | color_gray_dark" id="ctn_article_body"><p class=""></p></div>

如何解决这个问题?好吧,我再次尝试使用不同的解析器,在这种情况下,我使用了 "lxml" 而不是 "html.parser",并且它有效。

它选择了 div,所以只要改变这一行就可以了

soup = BeautifulSoup(text,"lxml")

当然你需要安装这个解析器。