【问题标题】:Download files based on input list Python根据输入列表Python下载文件
【发布时间】:2014-11-02 01:07:48
【问题描述】:

我正在尝试根据给定列表下载文件。我的脚本对我来说做得很好。但是,我有一个问题。它只下载第一个。它不会遍历列表。我稍微修改了代码,现在它考虑将列表中的所有元素视为一个元素,并返回错误消息“没有这样的文件或目录数据\item1\nitem2\nitem3\nitem4\nitem5.txt” 这是一部分我的解析输入列表的代码。

def get_data(name):
    file_name = os.path.join("data", name + ".txt")
    if not os.path.exists(file_name):
        sys.exit(-1)

    inF = open(file_name, "r") 
    lines = inF.readlines()
    data = ''.join(lines)

    return data 

编辑:

def download_final_data_for_data(data):
    url = "http://www.example.com/"+ data
    url_file = urlopen(url)
    soup = BeautifulSoup(url_file)
    soup1 = str(soup)
    pattern=re.compile(r'''>final_data(.*?)</a>''')  
    data = pattern.findall(soup1)
    final_data_number = ''.join(data)
    return final_data_number

def get_data(name):
    data_list = []
    file_name = os.path.join("data", name + ".txt")
    if not os.path.exists(file_name):
        sys.exit(-1)

    inF = open(file_name, "r") 
    lines = inF.readlines()
    for line in lines:
        data = line.strip()
        if len(data) > 1:
            data_list.append(data)
        else:
            data_list.append(sys.argv[1])
    return data_list

【问题讨论】:

  • “数据”是字符串还是列表?
  • 您应该可能会遍历函数之外的名称列表,然后只需传入您要处理的单个名称。
  • 您将什么name 参数传递给get_data()?你的输入文件是什么样的? readlines() 返回文件中的行列表,但在每个项目(字符串)的末尾留下\n
  • @martineau 实际上在它之前还有另一个脚本,我们在其中给出名称列表,它会为此下载数据。因此对于每个 name.txt 将是其对应的数据。现在我需要给出相同的名称列表,从之前读取这些文件(这是这里的数据输入)。它有多条线路。我的脚本应该一次占用一行。
  • 您的data = ''.join(lines) 语句将返回的所有项目readlines() 合并为一个字符串(其中包括列表中每个项目末尾的\n)。目前尚不清楚为什么错误消息包含“data\item1\nitem2\nitem3\nitem4\nitem5.txt”,特别是因为您在尝试open() 文件之前有一个os.path.exists() 调用。

标签: python list file parsing download


【解决方案1】:

由于您的陈述不是很清楚,我将尝试展示我解决此类任务的方法的框架。

您可以使用 argparse 告诉程序使用某些文件作为链接列表。

Argparse 在下面的脚本中提供了一个 CLI 接口,您可以像这样调用它。

python ./script.py -i list.txt -o ./

将所有内容下载到当前目录(注意这没有实现) 或者通过使用一堆文件 python ./script.py -i lists/* -o ./

import argparse   

def parseList(file):   # Parse the file, remove newlines/empty lines

    with open(file, 'r') as f: 
        lines = [line.strip() for line in f if line.strip()]
    return lines


def downloadLinks(links, output): # DOWNLOAD ALL THE LINKS!
    for link in links:
        print("Download me: %s" % link)

if __name__ == '__main__':

    ap = argparse.ArgumentParser('File Downloader')

    ap.add_argument('-i','--input',nargs='+', required=True, help='Path to the download list')
    ap.add_argument('-o','--output',required=True, help='Path to the output directory')

    args = vars(ap.parse_args())



    for file in args['input']:  # loop over all input files and process them
        parsedList = parseList(file)
        downloadLinks(parsedList, args['output'])

【讨论】:

    【解决方案2】:

    我知道问题出在哪里。有问题的部分是:

    file_name = os.path.join("data", name + ".txt")
    

    为了获得正确的文件名,您必须以某种方式遍历名称。为了在您阅读它们时获取您的姓名列表(并且它们现在存在于代码中),请执行

    namelist = name.split("/n") #this gives you a list that you can work on.
                                #alternatively read the file line-by-line (which you don't at the moment)
    

    您的代码所做的是加入包含 "data" 的字符串,您读取的所有名称都带有换行符和 ".txt" 后缀。无论如何,那就做一个

    for name in namelist:
        #do stuff with name
        file_name = os.path.join("data",name+".txt")
        ....
    

    【讨论】:

      【解决方案3】:

      我假设您将字符串传递给 get_data() ,否则会出现连接错误。如果是这种情况,由于您在错误中获得的文件名包括换行符,并且您在方法结束时加入了所有内容,我猜您正在加入文件中的全部输入。但是,如果不查看“名称”是什么,我无法确定。

      如果你正在这样做,我建议使用 file.readlines() 并将其传递给 get_data。它看起来像:

      for name in file.readlines():
          data = get_data(name)
      

      否则,如果你出于某种原因需要将它全部读入一个字符串,你可以尝试:

      names = name.split('\n')
      for name in names:
          data = get_data(name)
      

      【讨论】:

        【解决方案4】:
        for name in namelist.split('\\'):
            data = get_data(name)
        

        【讨论】:

          【解决方案5】:

          如果没有更多上下文和具体示例输入,很难说,但看起来name 包含类似item1\nitem2\nitem3\nitem4\nitem5 的内容。你打印出来检查了吗?

          我注意到您将lines 连接成一个字符串data。如果您使用参数 name 执行类似操作,我希望看到您所描述的内容。

          我猜你可能想做的是这样的:

          for fn in name:
              get_data(fn.strip())  # strip off possible trailing \n
          

          但没有先加入name。如果name 已经是您描述的字符串,那么您需要执行以下操作:

          name = name.split('\n')
          for fn in name:
              get_data(fn)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-10-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-08
            • 1970-01-01
            相关资源
            最近更新 更多