【问题标题】:How do I properly write a CSV file within a for loop in python?如何在 python 的 for 循环中正确编写 CSV 文件?
【发布时间】:2021-05-05 02:10:14
【问题描述】:

我正在使用以下代码从网页中抓取内容,最终目标是写入 CSV。在第一次迭代中,我让这部分工作,但现在我的数据格式不同,它以一种在我尝试在 excel 中查看数据时被破坏的方式写入数据。

如果我使用下面的代码,在 Excel 中查看时,“heading.text”数据会正确放入一个单元格中。其中“child.text”的内容被打包到一个单元格中,而不是根据逗号进行拆分。您会看到我已尝试清理“child.text”的内容,以查看这是否是我的问题。

如果我从“z”中删除“heading.text”并重试,它会以一种让 excel 每个单元格显示一个字母的方式写入。最后,我希望在 excel 中查看时,用逗号分隔的每个值都显示在一个单元格中,我相信我在构造“z”时或者在写行时做错了一些事情(很多事情?)。

任何指导将不胜感激。谢谢。

    csvwriter = csv.writer(csvfile) 
    for heading in All_Heading:
        driver.execute_script("return arguments[0].scrollIntoView(true);", heading)
        print("------------- " + heading.text + " -------------")
        ChildElement = heading.find_elements_by_xpath("./../div/div")
        for child in ChildElement:
            driver.execute_script("return arguments[0].scrollIntoView(true);", child)
            #print(heading.text)
            #print(child.text)
            z = (heading.text, child.text)
            print (z)
            csvwriter.writerow(z)

当我打印“z”时,我得到以下信息:

('Flower', 'Afghani 3.5g Pre-Pack Details\nGREEN GOLD ORGANICS\nAfghani 3.5g Pre-Pack\nIndica\nTHC: 16.2%\n1/8 oz  -  \n$45.00')

当我使用在“\n”上拆分字符串的旧代码打印“z”时,我得到以下信息:

('Flower', "Cherry Limeade 3.5g Flower - BeWell Details', 'BE WELL', 'Cherry Limeade 3.5g Flower - BeWell', 'Hybrid', 'THC: 18.7 mg', '1/8 oz  -  ', '$56.67")

【问题讨论】:

  • 为什么要将 child.text 分成几行?是否可以为其提供示例文本?
  • 我在测试看看\n是否有问题,我将更新代码并添加它的打印内容作为示例。

标签: python selenium csv screen-scraping


【解决方案1】:

csv.writerow() 接受一个可迭代对象,其中每个元素都由作者的分隔符分隔,即创建一个不同的单元格。

首先让我们看看你到现在为止发生了什么:

  1. (heading.text, child.text) 有两个元素,即两个单元格,heading.text 和 child.text
  2. (child.text) 只是 child.text (如果是 (child.text**,**) 则将是一个元组),并且字符串的元素是每个字母。因此,每个字母都有自己的单元格。

要连续获取不同的单元格,我们需要在可迭代对象中使用单独的元素,因此我们需要像 [header.text, child.text line 1, child.text line 2, ...] 这样的可迭代对象。您将文本分成几行是正确的,但没有正确添加这些行。 元组是不可变的,我将使用列表来代替:

  1. 我们知道heading.text 是单个单元格,因此我们可以编写以下内容开始
row  = [heading.text] # this is what your z is
  1. 我们希望每一行都是一个单独的元素,所以我们拆分 child.text:
lines = child.text.split("\n") 
# The text doesn’t start or end with a newline so this should suffice
  1. 现在我们希望将每个元素分别添加到行中,我们可以在列表中使用 extend() 方法:
row.extend(lines)
# [1, 2].extend([3, 4, 5]) would result in [1, 2, 3, 4, 5]

累积它:

row  = [heading.text]
lines = child.text.split("\n") 
row.extend(lines)

或在一行中解压:

row = [heading.text, *child.text.split("\n")] # You can also use a tuple here

【讨论】:

  • 非常感谢。有一点要澄清这可能需要自己的问题,但在写语句中是否有可能知道我正在写的元素名称或路径?有些项目缺少数据点,我想检测它是否“空白”,但由于空白意味着它甚至不存在,我对如何检查这一点感到困惑。
  • 我不确定您所说的数据点是什么意思,但这听起来可能。为此创建一个新问题,我会检查一下。最好不要在这里改变问题的范围。
猜你喜欢
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
  • 2019-06-21
  • 2018-01-12
  • 2018-03-14
  • 2015-08-12
  • 2021-04-17
  • 1970-01-01
相关资源
最近更新 更多