Использование Python для загрузки документа, на который нет явной ссылки в URL - PullRequest
1 голос
/ 21 октября 2010

Я написал веб-сканер на Python 2.6, используя Bing API, который ищет определенные документы, а затем загружает их для классификации позже.Я использовал строковые методы и urllib.urlretrieve() для загрузки результатов, URL которых заканчивается на .pdf, .ps и т. Д., Но у меня возникают проблемы, когда документ «спрятан» за URL, например:

http://www.oecd.org/officialdocuments/displaydocument/?cote=STD/CSTAT/WPNA(2008)25&docLanguage=En

Итак, два вопроса.Есть ли вообще способ определить, есть ли в URL файл pdf / doc и т. Д., На который он ссылается, если он не делает этого явно (например, www.domain.com/file.pdf)?Есть ли способ заставить Python поймать этот файл?

Редактировать: Спасибо за ответы, некоторые из которых предлагают загрузить файл, чтобы проверить, имеет ли он правильный тип.Единственная проблема ... я не знаю, как это сделать (см. Вопрос № 2 выше).urlretrieve(<above url>) дает только html-файл с href, содержащим тот же URL.

Ответы [ 7 ]

8 голосов
/ 21 октября 2010

Невозможно сказать по URL, что он вам даст. Даже если он заканчивается на .pdf, он все равно может дать вам HTML или что-нибудь еще.

Вы можете сделать запрос HEAD и посмотреть тип контента, который, если сервер не обманывает вас, сообщит вам, если это PDF.

В качестве альтернативы вы можете скачать его, а затем выяснить, является ли то, что вы получили, PDF-файлом.

3 голосов
/ 21 октября 2010

В этом случае то, что вы называете «документом, на который явно не ссылаются в URL», представляется так называемым «перенаправлением». По сути, сервер сообщает вам, что вы должны получить документ по другому URL. Как правило, urllib python будет автоматически следовать этим перенаправлениям, так что вы получите правильный файл. (и - как уже упоминали другие - вы можете проверить заголовок MIME-типа ответа, чтобы увидеть, является ли это PDF).

Однако рассматриваемый сервер делает здесь что-то странное. Вы запрашиваете URL, и он перенаправляет вас на другой URL. Вы запрашиваете другой URL, и он снова перенаправляет вас ... на тот же URL! И снова ... И снова ... В какой-то момент urllib решает, что этого уже достаточно, и перестанет следовать перенаправлению, чтобы избежать попадания в бесконечный цикл.

Так почему же вы можете получить PDF, когда используете браузер? Потому что, очевидно, сервер будет обслуживать PDF, только если у вас включены куки. (почему? вы должны спросить людей, ответственных за сервер ...) Если у вас нет куки, он просто будет перенаправлять вас вечно.

(проверьте urllib2 и cookielib , чтобы получить поддержку для файлов cookie, это руководство может помочь)

По крайней мере, именно это, я думаю, и является причиной проблемы. На самом деле я еще не пробовал делать это с куки. Может также случиться так, что сервер не «хочет» обслуживать pdf, потому что он обнаруживает, что вы не используете «нормальный» браузер (в этом случае вам, вероятно, придется возиться с заголовком User-Agent), но это было бы странным способом сделать это. Поэтому я предполагаю, что он где-то использует «сессионный cookie», а в случае, если у вас его еще нет, продолжает пытаться перенаправить.

2 голосов
/ 21 октября 2010

Как уже было сказано, нет способа отличить тип контента от URL.Но если вы не возражаете получить заголовки для каждого URL, вы можете сделать следующее:

obj = urllib.urlopen(URL)

headers = obj.info()
if headers['Content-Type'].find('pdf') != -1:
   # we have pdf file, download whole
...

Таким образом, вам не нужно загружать каждый URL, только его заголовки.Это все еще не совсем экономит сетевой трафик, но вы не станете лучше.

Также вы должны использовать mime-типы вместо моей грубой находки ('pdf').

0 голосов
/ 06 сентября 2016

Определите тип файла в Python 3.x и webapp с URL-адресом файла, который не может иметь расширение или поддельное расширение.Вы должны установить python-magic, используя

pip3 install python-magic

. Для Mac OS X вы также должны установить libmagic, используя

brew install libmagic

Фрагмент кода

import urllib
import magic
from urllib.request import urlopen

url = "http://...url to the file ..."
request = urllib.request.Request(url)
response = urlopen(request)
mime_type = magic.from_buffer(response.read())
print(mime_type)
0 голосов
/ 21 октября 2010

Вы не можете видеть это непосредственно из URL.Вы можете попробовать загрузить только заголовок HTTP-ответа и найти заголовок Content-Type.Однако вы должны доверять серверу в этом - он может ответить неправильным заголовком Content-Type, не соответствующим данным, представленным в теле.

0 голосов
/ 21 октября 2010

Проверьте тип mime с помощью функции urllib.info().Это может быть не на 100% точно, это действительно зависит от того, что сайт возвращает в качестве заголовка Content-Type.Если он будет вести себя хорошо, он вернет правильный тип MIME.

PDF должен вернуть application / pdf, но это может быть не так.

В противном случае вам, возможно, придется просто загрузить его ипопробуй.

0 голосов
/ 21 октября 2010

Нет. Невозможно определить, на какой ресурс ссылается URL, просто взглянув на него. Сервер сам решает, что он вам даст, когда вы запрашиваете определенный URL.

...