【问题标题】:After reading urls from a text file, how can I save all the responses into separate files?从文本文件中读取 url 后,如何将所有响应保存到单独的文件中?
【发布时间】:2020-08-13 15:54:33
【问题描述】:

我有一个脚本,它从文本文件中读取 url,执行请求,然后将所有响应保存在一个文本文件中。如何将每个响应保存在不同的文本文件中,而不是全部保存在同一个文件中?例如,如果我标记为 input.txt 的文本文件有 20 个 url,我想将响应保存在 20 个不同的 .txt 文件中,例如 output1.txt、output2.txt,而不仅仅是一个 .txt 文件。因此,对于每个请求,响应都会保存在一个新的 .txt 文件中。谢谢

import requests
from bs4 import BeautifulSoup


with open('input.txt', 'r') as f_in:
    for line in map(str.strip, f_in):
        if not line:
            continue

        response = requests.get(line)
        data = response.text
        soup = BeautifulSoup(data, 'html.parser')
        categories = soup.find_all("a", {"class":'navlabellink nvoffset nnormal'})

        for category in categories:
            data = line + "," + category.text

            with open('output.txt', 'a+') as f:
                f.write(data + "\n")
                print(data)            

【问题讨论】:

  • 您的缩进有误?这只会使用文件中的最后一行
  • @MZ 嗨,谢谢,你能指定哪些缩进吗?这段代码在我构建时运行良好
  • 您回复的所有内容都应缩进for line in map(str.strip, f_in):?
  • @MZ 谢谢,创建列表时出错。现已修复

标签: python file beautifulsoup python-requests http-post


【解决方案1】:

这是实现其他人暗示的快速方法:

import requests
from bs4 import BeautifulSoup


with open('input.txt', 'r') as f_in:
    for i, line in enumerate(map(str.strip, f_in)):
        if not line:
            continue

        ...

            with open(f'output_{i}.txt', 'w') as f:
                f.write(data + "\n")
                print(data)  

【讨论】:

  • 这样做的警告是,以后无法以编程方式将相同的 URL 映射到文件。通过使用散列函数,只要您有相同的链接,您就可以随时获取文件名。
【解决方案2】:

您可以使用open('something.txt', 'w') 创建一个新文件。如果找到该文件,它将删除其内容。否则,它将创建一个名为“something.txt”的新文件。现在,您可以使用file.write() 写您的信息!

【讨论】:

  • 所以如果我在一个 .txt 文件中有 20 个 url,我必须以 20 种不同的方式编写 open('something.txt', 'w')?
  • 对,就是打开它。但请确保如果您使用open(),您必须在完成后使用file.close()。如果不这样做,文件将保持打开状态,并且可能会导致问题。
  • OP 使用内置 context manager ,因此不需要显式关闭文件。在 with 块完成后它会自动关闭。
【解决方案3】:

我不确定我是否正确理解了您的问题。

我将创建一个数组/列表,并为每个 url 请求和响应创建一个对象。然后将对象添加到数组/列表中,并为每个对象写入不同的文件。

【讨论】:

  • 例如,如果我标记为 input.txt 的文本文件有 20 个 url,我想将响应保存在 20 个不同的 .txt 文件中,例如 output1.txt、output2.txt 而不是一个 .txt文件。因此,对于每个请求,响应都会保存在一个新的 .txt 文件中。
  • 您也可以逐行阅读 input.txt 行。例如: f = open("input.txt", "r") for x in f: input = open("input" + x + ".txt", "w") line = f.readline() input.write (line) input.close() 不知道这段代码是否正确,但你知道我的意思。
【解决方案4】:

至少有两种方法可以为每个 url 生成文件。一个,如下所示,是创建文件的一些数据唯一数据的哈希。在这种情况下,我选择了类别,但您也可以使用文件的全部内容。这将创建一个用于文件名的唯一字符串,以便具有相同类别文本的两个链接在保存时不会相互覆盖。

另一种方法(未显示)是在数据本身中找到一些唯一值并将其用作文件名而不对其进行哈希处理。但是,这可能会导致比它解决的问题更多的问题,因为不应信任 Internet 上的数据。

这是您的代码,其中包含用于文件名的 MD5 哈希。 MD5 is not a secure hashing function 用于密码,但创建唯一文件名是安全的。

更新片段

import hashlib

import requests
from bs4 import BeautifulSoup



with open('input.txt', 'r') as f_in:
    for line in map(str.strip, f_in):
        if not line:
            continue

    response = requests.get(line)
    data = response.text
    soup = BeautifulSoup(data, 'html.parser')
    categories = soup.find_all("a", {"class":'navlabellink nvoffset nnormal'})

    for category in categories:
        data = line + "," + category.text
        filename = hashlib.sha256()
        filename.update(category.text.encode('utf-8'))
        with open('{}.html'.format(filename.hexdigest()), 'w') as f:
            f.write(data + "\n")
            print(data)        

添加代码

filename = hashlib.sha256()
filename.update(category.text.encode('utf-8'))
with open('{}.html'.format(filename.hexdigest()), 'w') as f:

捕获更新的页面

如果您关心在不同时间点捕获页面内容,请对文件的全部内容进行哈希处理。这样,如果页面中的任何内容发生更改,则页面之前的内容不会丢失。在这种情况下,我对 url 和文件内容进行哈希处理,并将哈希值与 URL 哈希值和文件内容的哈希值连接起来。这样,当目录被排序时,文件的所有版本都是可见的。

hashed_contents = hashlib.sha256()
hashed_contents.update(category['href'].encode('utf-8'))
with open('{}.html'.format(filename.hexdigest()), 'w') as f:

for category in categories:
        data = line + "," + category.text
        hashed_url = hashlib.sha256()
        hashed_url.update(category['href'].encode('utf-8'))
        page = requests.get(category['href'])
        hashed_content = hashlib.sha256()
        hashed_content.update(page.text.encode('utf-8')
        filename = '{}_{}.html'.format(hashed_url.hexdigest(), hashed_content.hexdigest())
        with open('{}.html'.format(filename.hexdigest()), 'w') as f:
            f.write(data + "\n")
            print(data)       

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 2015-02-09
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多