【问题标题】:Downloading a pdf file in python with urllib results in some html garbage使用 urllib 在 python 中下载 pdf 文件会导致一些 html 垃圾
【发布时间】:2019-02-15 18:56:28
【问题描述】:

我正在尝试使用 Python 3 的 urllib 下载文件,但我得到了一些 html 垃圾而不是实际文件。但是,如果我使用浏览器,我可以下载文件就好了。一个最小的非工作示例:

import urllib.request

url = 'https://contrataciondelestado.es/wps/wcm/connect/PLACE_es/Site/area/docAccCmpnt?srv=cmpnt&cmpntname=GetDocumentsById&source=library&DocumentIdParam=ecd194a4-82e1-4fd2-8135-616622234f9b'

urllib.request.urlretrieve(url,'blah.pdf')

我还尝试了this thread 中的两个答案(创建用户代理 并使用requestsmodule)...但同样没有。

使用requests

import requests

url = 'https://contrataciondelestado.es/wps/wcm/connect/PLACE_es/Site/area/docAccCmpnt?srv=cmpnt&cmpntname=GetDocumentsById&source=library&DocumentIdParam=ecd194a4-82e1-4fd2-8135-616622234f9b'
r = requests.get(url, allow_redirects=True)
with open('test.pdf', 'wb') as f:
    f.write(r.content)
print(r.is_redirect)

同样的废话,requests 模块说传递的 URL 不是 重定向

我还尝试了更多“复杂”的东西,例如 download_file 建议的函数 here......还是老样子。

有什么线索吗?

干杯。

【问题讨论】:

标签: python python-3.x http


【解决方案1】:

您用于执行下载的 URL 不是最后一个,有一个重定向(来自 HTML 源)。

$ curl -I "https://contrataciondelestado.es/wps/wcm/connect/PLACE_es/Site/area/docAccCmpnt?srv=cmpnt&cmpntname=GetDocumentsById&source=library&DocumentIdParam=ecd194a4-82e1-4fd2-8135-616622234f9b"
HTTP/1.1 200 OK
Date: Tue, 11 Sep 2018 09:44:41 GMT
ETag: "-1462112711"
Content-Length: 435
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Cache-Control: no-cache="set-cookie, set-cookie2"
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8
Content-Language: en-US
Location: https://contrataciondelestado.es
Set-Cookie: JSESSIONID=0000t4dCqcAT246C2R0a6jwMpsq:prodnod5; Path=/; Domain=.contrataciondelestado.es; Secure
Set-Cookie:  JSESSIONID=0000t4dCqcAT246C2R0a6jwMpsq:prodnod5; Path=/; Domain=.contrataciondelestado.es; Secure
Connection: close


<link
    href='/wps/CacheProxyServlet/colorPalette/default/browserVendor/unknown/browserName/Default+HTML+Client/browserVersion/unknown/locale/es/forwardurl/TemaPlace/themes/html/TemaPlace/./styles.jsp'
    rel="styleSheet" type="text/css">

<meta http-equiv="refresh" content="0;url='/wps/wcm/connect/bb876769-1b16-4f8b-84fc-b85d5f864e07/DOC20120619092407Pliego+campamentos+verano.pdf?MOD=AJPERES'">

你必须从meta http-equiv="refresh"标签中提取正确的URL:

https://contrataciondelestado.es/wps/wcm/connect/bb876769-1b16-4f8b-84fc-b85d5f864e07/DOC20120619092407Pliego+campamentos+verano.pdf?MOD=AJPERES

【讨论】:

  • 这可行,但我的目标是更便携。这意味着,如果可能的话,只使用 Python 的标准(或一些众所周知的)库
【解决方案2】:

最后,我最终使用了 Antwane 的解决方案。仅供参考:

我使用 Python 的标准库下载了文件

urllib.request.urlretrieve(url, 'aux')

这给了我一个包含重定向的文本(实际上是 html)文件(名为“aux”)。我读到了

with open('aux') as f:
    html = f.read()

并构建了一个正则表达式

regex_url_from_http_equiv = re.compile('<meta http-equiv="refresh" content="0;url=\'/(.*)\'')

提取工作 URL

redirection_match = self.regex_url_from_http_equiv.search(html)

# here you would write the usual checks and whatelse...
if redirection_match:
    redirection = redirection_match.group(1)

不是一个的解决方案,但现在已经足够了。

谢谢大家的意见!!

【讨论】:

    猜你喜欢
    • 2011-02-24
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 2011-06-13
    • 1970-01-01
    相关资源
    最近更新 更多