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

时间:2018-05-06 05:51:43

标签: python redirect download python-requests urllib3

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

模式

注意:最后一部分会更改其他文件和NO pdf文件扩展名。

但是,如果您在浏览器中添加此链接,则可以清楚地看到该链接从{}变为http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sboa263,并最终更改为http://www.ti.com/lit/an/sboa263/sboa263.pdf 现在我知道你可以告诉我“很好,然后按照这种模式”。但我不想,因为IMO这不是解决这种自动化的正确方法。我希望能够从第一个链接本身下载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'))

要使用 -

到达重定向的网址
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">

下面的部分也显示了最终的网址,但我认为你明白了。我们可以利用这些信息吗?

1 个答案:

答案 0 :(得分:0)

正如Miraj50所提到的,确实是Meta Refresh将它带到了最终的网址。所以我从元标记中提取了最终的网址,并能够下载所有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:]