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:将一段文本放在一行中的主要内容,如果未能解决你的问题,请参考以下文章
QT textEdit里面有一段文本文字,在lineEdit输入一串字符串,点击一下pushbutton,在一个groupBox显示数量
BeautifulSoup文档2-详细方法 | 对象的种类有哪些?