首页 > 解决方案 > 在抓取 Python3 时仅将标头写入 CSV 一次

问题描述

所以,我正在上 Python3 的课程,在抓取部分,我们有一项任务是抓取http://quotes.toscrape.com/网站并获取所有引用的作者简介的文本、作者和链接,包括“下一页”上的内容。我已经这样做了,但是在我进入每个新页面后,我会得到一行我最初设想为标题的空行。

import requests
from bs4 import BeautifulSoup
import csv
from time import sleep

base_url = "http://quotes.toscrape.com"
url = "/page/1"

f = open("scraping_project_final.csv", "w")
f.truncate()
f.close()

while url:

    with open("scraping_project_final.csv", "a") as file:
        csv_writer = csv.writer(file)
        csv_writer.writerow(["text", "name", "url"])

        response = requests.get(f"{base_url}{url}")
        print(f"Scraping {base_url}{url}")
        soup = BeautifulSoup(response.text, "html.parser")
        quotes = soup.find_all(class_="quote")

        for quote in quotes:
            txt = quote.find(class_="text").get_text()
            author = quote.find(class_="author").get_text()
            link = quote.find("a")["href"]
            csv_writer.writerow([txt, author, link])

        next_page = soup.find(class_="next")
        url = next_page.find("a")["href"] if next_page else None
    # sleep(2)

所以,我遇到的问题是初始 writerrow 实际上每次迭代都会创建一个空行,我该如何避免这种情况?我想继续这种方法,如果可能的话不要使用 DictReader。我在下面添加了一张图片,即 CSV 输出。可以看到,十行之后,有一行只有:text、names、url。

CSV 输出

标签: python-3.xcsvweb-scrapingbeautifulsoupwith-statement

解决方案


只打开文件一次,写一次标题,然后在页面上循环。例如:

with open('scraping_project_final.csv', 'w', encoding='utf-8-sig', newline='') as file:
    csv_writer = csv.writer(file)
    csv_writer.writerow(['text', 'name', 'url'])

    while url:

        response = requests.get(f'{base_url}{url}')
        ...

无需为每一页重新打开文件,也无需截断文件。

Noteutf-8-sig是在 Excel 中打开的最佳编码,因为它处理 Unicode 字符并newline=''记录为打开csv.writer文件的模式。


推荐阅读