【问题标题】:How to read a file downloaded by selenium webdriver in python如何在python中读取selenium webdriver下载的文件
【发布时间】:2016-04-26 06:52:51
【问题描述】:

我在 python 中使用 selenium 和 webdriver 从站点下载 csv 文件。该文件被下载到指定的下载目录中。这是我的代码的概述

fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList", 2)
fp.set_preference("browser.download.manager.showWhenStarting", False)
fp.set_preference("browser.download.dir",'xx/yy')
fp.set_preference('browser.helperApps.neverAsk.saveToDisk', "text/plain, application/vnd.ms-excel, text/csv, text/comma-separated-values, application/octet-stream")
driver = webdriver.Firefox(fp)
driver.get('url')

我需要 print 将此 csv 的内容发送到终端。许多具有随机名称的类似文件将被下载到同一个文件夹中,因此通过文件名访问文件将不起作用,因为我不知道它会提前是什么

【问题讨论】:

  • 你不能用selenium打开和读取csv文件,你需要使用文件阅读器库。
  • 你能发布html吗?也许你可以从那里提取文件名
  • 文件名不在 html 中的任何位置。对不起,它的敏感信息,所以我不能发布它。不过我已经彻底检查过了。我有一种感觉,我可能必须使用文件库读取文件,但我仍然需要正确的文件名。有没有办法在 driver.get() 中查看文件名,或者有没有办法从屏幕响应中打印文件内容?
  • Autoit 提供windows界面,包括文件资源管理器。也许您可以使用它按日期获取文件(例如上次下载),但我不确定。
  • 我必须在 ubuntu 服务器上运行它,并且将有几个(1000 +)此代码实例同时运行,因此按日期获取文件是不可靠的

标签: python selenium selenium-webdriver web-scraping webdriver


【解决方案1】:

这个答案是由以前的堆栈溢出问题、答案以及这篇文章中的 cmets 组合而成的,所以谢谢大家。

我为这个解决方案结合了 selenium webdriver 和 python requests 模块。我基本上是使用 selenium 登录网站,从 webdriver 会话中复制 cookie,然后使用 requests.get(url,cookies = webdriver_cookies) 来获取文件。

这是我的解决方案的要点

fp = webdriver.FirefoxProfile() 
fp.set_preference("browser.download.folderList", 2)
fp.set_preference("browser.download.manager.showWhenStarting", False) 
fp.set_preference("browser.download.dir",'xx/yy') 
fp.set_preference('browser.helperApps.neverAsk.saveToDisk', "text/plain, application/vnd.ms-excel, text/csv, text/comma-separated-values, application/octet-stream") 
driver = webdriver.Firefox(fp)

# selenium login code ...

driver_cookies = driver.get_cookies()
cookies_copy = {}
for driver_cookie in driver_cookies:
    cookies_copy[driver_cookie["name"]] = driver_cookie["value"]
r = requests.get('url',cookies = cookies_copy)
print r.text

我希望这对某人有所帮助

【讨论】:

    【解决方案2】:

    在 Selenium 中下载文件绝不是一个好主意。您无法控制文件下载的位置和文件名,如果您想找出答案,则必须使用脏黑客。这取决于浏览器及其设置,以及之前是否已经下载过相同的文件。

    另外,您必须注意在下载后删除文件,否则,同一文件的多个副本会向您的硬盘发送垃圾邮件,直到硬盘完全装满。

    如果可能的话,你应该调用类似的东西

    string downloadUrl = ButtonDownloadPdf.GetAttribute("href");
    

    然后自己处理下载,使用常规方法,而不是 Selenium。

    【讨论】:

    • 它不是我的首选。这是最后的手段
    • @Kimmy 你愿意解释为什么这不是一个好主意,还是你宁愿冒险投反对票?如果测试用例要求下载和检查文件,那么为什么不使用 Selenium 自动化呢?
    • @Kimmy 感谢您的详细说明。我仍然不同意三个原因 1)您可以控制文件的下载位置(浏览器设置)并且文件至少有一个默认名称; 2) 如果测试失败,您不应该删除文件下载后 以便能够检查文件。您应该运行自动化测试进行清理之前删除旧文件。有什么问题吗? 3) 即使您声称使用所有可能的浏览器自动测试所有内容,其他人可能会满足于仅使用一个浏览器运行一些奇特的测试 - 而不是手动或不测试
    • 在 Selenium 中下载文件的一个用例是抓取不会以明显方式公开链接的网站
    【解决方案3】:

    您可以从该位置获取最后下载的文件,然后读取该文件:

    path = /path to folder
    list = os.listdir(path)
    time_sorted_list = sorted(list, key=os.path.getmtime)
    file_name = time_sorted_list[len(time_sorted_list)-1]
    

    然后你可以从这个文件中读取。希望不会有多个文件通过并行进程到达那里。

    编辑: 刚刚看到有多个实例可供下载的评论,因此您可以使用 urllib 并使用其 url 下载文件:

    import urllib
    urllib.urlretrieve( "http://www.example.com/yourfile.ext", "your-file-name.ext") // you can provide unique-id to your file name
    

    【讨论】:

    • 这不起作用,因为我从中下载文件的站点需要登录,因此会话数据由 selenium 完成。会话数据与 webdriver 对象相关联。所以一个简单的 urlretrieve() 给了我一个 IOError: ('http error', 401, 'Unauthorized')
    猜你喜欢
    • 2017-11-04
    • 2017-08-26
    • 1970-01-01
    • 2018-04-06
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    相关资源
    最近更新 更多