将一系列的字符串(加上一个数字)写入csv的一行中[英] Write series of strings (plus a number) to a line of csv

本文是小编为大家收集整理的关于将一系列的字符串(加上一个数字)写入csv的一行中的处理方法,想解了将一系列的字符串(加上一个数字)写入csv的一行中的问题怎么解决?将一系列的字符串(加上一个数字)写入csv的一行中问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

这不是漂亮的代码,但是我有一些代码可以从HTML文件中抓住一系列字符串,并给我一系列字符串:author,title,date,date,length,.我有2000多个HTML文件,我想浏览所有文件,并将此数据写入单个CSV文件.我知道所有这些都必须最终将其包裹在一个for循环中,但是在此之前,我很难理解如何从获得这些值到将它们写入CSV文件.我的想法是首先创建列表或元组,然后将其写入CSV文件中的一行:

the_file = "/Users/john/Code/tedtalks/test/transcript?language=en.0"
holding = soup(open(the_file).read(), "lxml")
at = holding.find("title").text
author = at[0:at.find(':')]
title  = at[at.find(":")+1 : at.find("|") ]
date = re.sub('[^a-zA-Z0-9]',' ', holding.select_one("span.meta__val").text)
length_data = holding.find_all('data', {'class' : 'talk-transcript__para__time'})
(m, s) = ([x.get_text().strip("\n\r") 
      for x in length_data if re.search(r"(?s)\d{2}:\d{2}", 
                                        x.get_text().strip("\n\r"))][-1]).split(':')
length = int(m) * 60 + int(s)
firstpass = re.sub(r'\([^)]*\)', '', holding.find('div', class_ = 'talk-transcript__body').text)
text = re.sub('[^a-zA-Z\.\']',' ', firstpass)
data = ([author].join() + [title] + [date] + [length] + [text])
with open("./output.csv", "w") as csv_file:
        writer = csv.writer(csv_file, delimiter=',')
        for line in data:
            writer.writerow(line)

我不能为自己的生命而弄清楚如何让python尊重这些是字符串的事实,应该将其存储为字符串,而不是字母列表. (上面的.join()是我试图弄清楚的.)

向前看:以这种方式处理2000个文件,将它们剥离到我想要的东西,并一次编写CSV的一行,或者更好地构建pandas>和然后写给CSV? (所有2000个文件= 160MB,因此被剥离,最终数据不能超过100MB,因此在这里没有大尺寸,但是最终可以最终成为一个问题.)

推荐答案

这将获取所有文件并将数据放入CSV中,您只需要将路径传递到包含HTML文件的文件夹和输出文件的名称:

import re
import csv
import os
from bs4 import BeautifulSoup
from glob import iglob


def parse(soup):
    # both title and author are can be parsed in separate tags.
    author = soup.select_one("h4.h12.talk-link__speaker").text
    title = soup.select_one("h4.h9.m5").text
    # just need to strip the text from the date string, no regex needed.
    date = soup.select_one("span.meta__val").text.strip()
    # we want the last time which is the talk-transcript__para__time previous to the footer.
    mn, sec = map(int, soup.select_one("footer.footer").find_previous("data", {
        "class": "talk-transcript__para__time"}).text.split(":"))
    length = (mn * 60 + sec)
    # to ignore time etc.. we can just pull from the actual text fragment and remove noise i.e (Applause).
    text = re.sub(r'\([^)]*\)',"", " ".join(d.text for d in soup.select("span.talk-transcript__fragment")))
    return author.strip(), title.strip(), date, length, re.sub('[^a-zA-Z\.\']', ' ', text)

def to_csv(patt, out):
    # open file to write to.
    with open(out, "w") as out:
        # create csv.writer.
        wr = csv.writer(out)
        # write our headers.
        wr.writerow(["author", "title", "date", "length", "text"])
        # get all our html files.
        for html in iglob(patt):
            with open(html, as f:
                # parse the file are write the data to a row.
                wr.writerow(parse(BeautifulSoup(f, "lxml")))

to_csv("./test/*.html","output.csv")

本文地址:https://www.itbaoku.cn/post/1727742.html