Beautifulsoup to csv:将一段文本放在一行中

Posted

技术标签:

【中文标题】Beautifulsoup to csv:将一段文本放在一行中【英文标题】:beautifulsoup to csv: putting paragraph of text into one line 【发布时间】:2017-09-29 04:56:55 【问题描述】:

我有一堆网络文本,我想抓取并导出到 csv 文件。问题是文本在网站上被分成多行,beautifulsoup 就是这样读取它的。当我导出到 csv 时,所有文本都进入一个单元格,但该单元格有多行文本。当我尝试将 csv 读入另一个程序时,它会以一种产生无意义数据集的方式解释多行。问题是,在我用beautifulsoup 拉出文本之后但在导出到csv 之前,如何将所有文本放在一行中?

这是一个简单的工作示例,演示了多行的问题(实际上,生成的 csv 中的前几行是空白的,所以乍一看它可能看起来是空的):

import csv
import requests
from bs4 import BeautifulSoup

def main():
    r = requests.get("https://www.econometricsociety.org/publications/econometrica/2017/03/01/search-yield")
    soup = BeautifulSoup(r.text,"html.parser")
    with open('Temp.csv', 'w', encoding='utf8', newline='') as f:
        writer = csv.writer(f,delimiter=",")
        abstract=soup.find("article").text
        writer.writerow([abstract])

if __name__ == '__main__':
    main()

更新:有一些很好的建议,但它仍然不起作用。以下代码仍会在单元格中生成一个带有换行符的 csv 文件:

import csv    
import requests
from bs4 import BeautifulSoup

with open('Temp.csv', 'w', encoding='utf8', newline='') as f:
    writer = csv.writer(f,delimiter=',')
    r = requests.get("https://www.econometricsociety.org/publications/econometrica/2017/03/01/search-yield")
    soup = BeautifulSoup(r.text,'lxml') 
    find_article = soup.find('article')
    find_2para = find_article.p.find_next_sibling("p")
    find_largetxt = find_article.p.find_next_sibling("p").nextSibling
    writer.writerow([find_2para,find_largetxt])

这是基于不同建议的另一种尝试。这最终也会在 csv 文件中产生换行符:

import csv
import requests
from bs4 import BeautifulSoup

def main():
    r = requests.get("https://www.econometricsociety.org/publications/econometrica/2017/03/01/search-yield")
    soup = BeautifulSoup(r.text,"html.parser")
    with open('Temp.csv', 'w', encoding='utf8', newline='') as f:
        writer = csv.writer(f,delimiter=",")
        abstract=soup.find("article").get_text(separator=" ", strip=True)
        writer.writerow([abstract])

if __name__ == '__main__':
    main()

【问题讨论】:

您想从页面上抓取哪些典型的文本片段? 您是否可能只需要以下项目?:(1) 计量经济学:2017 年 3 月,第 85 卷,第 2 期 (2) Search for Yield (3) David Martinez‐Miera, Rafael Repullo ( 4) 我们提出了一个实际利率、信用利差与银行体系结构和风险之间关系的模型。银行介于企业家和投资者之间,可以监控企业家的项目。我们描述了固定总储蓄供给的均衡,... 其实我只是想要(4)。如果有一种简单的方法可以做到这一点,那就太棒了。 【参考方案1】:

将您的 abstract = ... 行更改为:

abstract = soup.find("article").get_text(separator=" ", strip=True)

它将使用 separator 参数分隔每一行(在这种情况下,它将用空格分隔字符串。

【讨论】:

这肯定看起来更好,但由于某种原因,“p”之间仍然存在换行符。和“第 351-378 页”中的“351-378”,这又会导致问题。【参考方案2】:
r = requests.get("https://www.econometricsociety.org/publications/econometrica/2017/03/01/search-yield")
soup = BeautifulSoup(r.text,'lxml') # I prefer using xml parser
find_article = soup.find('article')
# Next line how to find The title in this case: Econometrica: Mar 2017, Volume 85, Issue 2
find_title = find_article.h3
# find search yeild 
find_yeild = find_article.h1
#first_paragraph example : DOI: 10.3982/ECTA14057       p. 351-378
find_1para =  find_article.p
#second p example : David Martinez‐Miera, Rafael Repullo  
find_2para = find_article.p.find_next_sibling("p")
#find the large text area using e.g. 'We present a model of the relationship bet...'
find_largetxt = find_article.p.find_next_sibling("p").nextSibling

出于教育目的,我使用了多种方法来获取您想要的文本区域(您可以在每个区域上使用 .text 来获取不带标签的文本,或者您可以使用 Zroq 的方法。 但是您可以通过例如将这些中的每一个写入文件中

writer.writerow(find_title.text)

【讨论】:

效果很好,谢谢! (尽管仅供参考,我不得不用下划线替换“find.article”中的句点)。 是的,对不起,我现在就开始吧 :),如果一切正常,别忘了将问题标记为已回答。 不幸的是,它仍然无法正常工作。当我写入 csv 时,该条目仍然被分成多行,从而导致问题。这就是我为 csv writer 部分写的内容。 (另外,它不会让我添加“.text”,抱怨 'NavigableString' 对象没有属性 'text')与 open('Temp.csv', 'w', encoding='utf8', newline=' ') as f: writer = csv.writer(f,delimiter=",") writer.writerow([find_2para,find_largetxt]) 如果我不忘记,我稍后会看一下。也许我们朋友的代码可以完成这项工作,试一试。 你是说 Zroq 吗?我尝试在 find_largetxt 和 find_2para 的末尾添加“.nextSibling.get_text(separator=" ", strip=True)",但得到相同的 'NavigableString' 对象没有属性 'get_text' 错误...【参考方案3】:

最终对我有用的解决方案非常简单:

abstract=soup.find("article").text.replace("\t", "").replace("\r", "").replace("\n", "")

这消除了所有换行符。

【讨论】:

以上是关于Beautifulsoup to csv:将一段文本放在一行中的主要内容,如果未能解决你的问题,请参考以下文章

一段文快速带你入门Node.js和第三方模块

QT textEdit里面有一段文本文字,在lineEdit输入一串字符串,点击一下pushbutton,在一个groupBox显示数量

BeautifulSoup文档2-详细方法 | 对象的种类有哪些?

当我想要一列时,Python to CSV 将字符串分成两列

如何从 beautifulsoup 数据写入 csv

Python - 网页抓取 - BeautifulSoup & CSV