python - 即使使用 requests.history,从重定向 2 次的 URL 下载 pdf 文件也会失败

标签 python redirect download python-requests urllib3

我已经为此苦苦挣扎了一整天。我编译了通过在网页上使用 urllib3 获得的 URL 列表(也使用 BeautifulSoup)。 URL 基本上指向我想要自动下载的 pdf 文件。很棒的是 pdf 链接有漂亮的图案。所以我很容易使用正则表达式来制作我想要下载的 pdf 列表并忽略其余部分。但这就是问题开始的地方。 URL 遵循模式 http://www.ti.com/lit/sboa263

注意:最后一部分针对其他文件进行了更改,并且没有 pdf 文件扩展名。

但是如果您将此链接放入浏览器中,您可以清楚地看到它从该链接更改为 http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sboa263最终变成 http://www.ti.com/lit/an/sboa263/sboa263.pdf
现在我明白你可以告诉我“太好了,那就遵循这个模式”。但我不想,因为在我看来,这不是解决这种自动化的正确方法。我希望能够从第一个链接本身下载 pdf。

我已经尝试过

response = requests.get(url,allow_redirects=True)
这只会带我到第一个重定向的结果而不是最后一个文件。 甚至 response.history 也只带我到第一个重定向。

当我尝试下载该文件时,我得到了一个损坏的 pdf 文件,无法打开。然而,当我手动传递最终 URL 只是为了测试文件写入的正确性时,我得到了完美顺序的实际 pdf。 我不明白为什么请求无法到达最终网址。 我的完整代码如下供您引用 -

from bs4 import BeautifulSoup
import urllib3
import re
http = urllib3.PoolManager()
url = 'http://www.ti.com/analog-circuit/circuit-cookbook.html'
response = http.request('GET', url)
soup = BeautifulSoup(response.data)
find = re.compile("http://www.ti.com/lit/")
download_links = []
for link in soup.find_all('a'):
    match = re.match(find, link.get('href'))
    if match:
        #print(link.get('href'))
        download_links.append(link.get('href'))

要访问我使用的重定向 URL -

import requests
response = requests.get(download_links[45])
if response.history:
    print ("Request was redirected")
    for resp in response.history:
        final_url = resp.url
response = requests.get(final_url)

为了下载文件,我使用了下面的代码 -

with open('C:/Users/Dell/Desktop/test.pdf', 'wb') as f:
    f.write(response.content)

另外,我实际上只想传递一个文件夹名称,并且所有文件都应该使用 URL 本身最后一部分的名称下载。我还没弄清楚该怎么做。我尝试了 shutils 但没有成功。如果您也能帮助我完成这部分,那就太好了。

编辑:我将前两个 URL 传递给 Postman,并获得 HTML,而传递第三个 URL 将下载 pdf。在我得到的 HTML 中,我可以清楚地看到 Meta 属性之一列出了最终的 pdf URL。这是 Postman 结果的相关部分 -

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta content="IE=8;IE=9;IE=edge" http-equiv="x-ua-compatible">
        <meta content='width=device-width, initial-scale=1.0' name='viewport'>
        <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
        <META HTTP-EQUIV="Expires" CONTENT="-1">
        <META HTTP-EQUIV="Refresh" CONTENT="1; URL=http://www.ti.com/lit/an/sboa263/sboa263.pdf">

下面的部分还显示了最终 URL,但我想您已经明白了。我们可以利用这些信息吗?

最佳答案

正如Miraj50所述它确实是一次元刷新,将其带到了最终的网址。所以我从元标记中提取了最终的 url,并能够下载所有 45 个 pdf。下面是相同的代码 -

for links in download_links[5:]:
    response = requests.get(links)
    if response.history:
        print ("Request was redirected")
        print(response.url)
        r = response.url

从元标记获取链接 -

# The redirected url then uses meta refresh
meta_response = http.request('GET', r)
meta_soup = BeautifulSoup(meta_response.data)
meta_result = meta_soup.find('meta',attrs={'http-equiv':'Refresh'})
#print(meta_result)
wait,text = meta_result["content"].split(";")
final_url = text.strip()[4:]

关于python - 即使使用 requests.history,从重定向 2 次的 URL 下载 pdf 文件也会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50196650/

相关文章:

php - 更改站点的 URL 结构 - SEO 方法的正确技术 - 301 header ?

bash - 将多个 stdout 命令重定向到一个文件

android - 如何使用 AndroidAnnotations 使用进度条显示大文件的下载进度?

java - 如何使用 java 模拟损坏的应用程序/八位字节流

Python 多处理 - 为什么我的进程没有返回/完成?

python - 我怎样才能将这个方法重写为递归?

javascript - 为什么 anchor 在此脚本中不起作用?

c# - 等待重复下载不可靠?

python - 在 Python 中使用变量与 PostgreSQL 通信

从 MS Access 导入 Python : "Invalid connection string attribute"