Используйте httplib, чтобы проверить, вернет ли URL-адрес определенную страницу?

Я просматриваю несколько сотен ссылок на bit.ly, чтобы увидеть, использовались ли они для сокращения ссылки. Если ссылки нет, возвращается эта страница.

Как я могу просмотреть список ссылок, чтобы проверить, какие из них НЕ возвращают эту страницу?

Я попытался использовать метод головы, используемый в этот вопрос, однако он, конечно, всегда возвращал true.

Я просмотрел метод head, но обнаружил, что он никогда не возвращает никаких данных:

>>> import httplib
>>> conn = httplib.HTTPConnection("www.python.org")
>>> conn.request("HEAD","/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> data = res.read()
>>> print len(data)
0
>>> data == ''
True

Я в тупике на этом, и любая помощь будет здорово.


person Scherf    schedule 02.03.2014    source источник
comment
вы хотите получить содержимое страницы?   -  person Sharif Mamun    schedule 03.03.2014
comment
Я надеялся, что можно будет проверить ссылку, не загружая содержимое страницы, но если это единственный способ сделать это, то так тому и быть   -  person Scherf    schedule 03.03.2014
comment
проверить res.status (например, 301 — это перенаправление)   -  person jfs    schedule 03.03.2014
comment
когда ты получаешь 200 OK, тебе этого мало?   -  person Sharif Mamun    schedule 03.03.2014
comment
@Scherf: я попробовал вашу ссылку из вопроса, и она возвращает мне 404 (404 не перенаправляет, она не найдена).   -  person jfs    schedule 03.03.2014


Ответы (2)


Если bit.ly возвращает 404 http-код для несокращенных ссылок:

#!/usr/bin/env python
from httplib import HTTPConnection
from urlparse import urlsplit

urls = ["http://bit.ly/NKEIV8", "http://bit.ly/1niCdh9"]
for url in urls:
    host, path = urlsplit(url)[1:3]
    conn = HTTPConnection(host)
    conn.request("HEAD", path)
    r = conn.getresponse()
    if r.status != 404:
       print("{r.status} {url}".format(**vars()))

Не связано: для ускорения проверки можно использовать несколько потоков:

#!/usr/bin/env python
from httplib import HTTPConnection
from multiprocessing.dummy import Pool # use threads
from urlparse import urlsplit

def getstatus(url):
    try:
        host, path = urlsplit(url)[1:3]
        conn = HTTPConnection(host)
        conn.request("HEAD", path)
        r = conn.getresponse()
    except Exception as e:
        return url, None, str(e) # error
    else:
        return url, r.status, None

p = Pool(20) # use 20 concurrent connections
for url, status, error in p.imap_unordered(getstatus, urls):
    if status != 404:
       print("{status} {url} {error}".format(**vars()))
person jfs    schedule 02.03.2014
comment
Это работает отлично. Проблема, с которой я столкнулся, заключалась в том, что когда я импортировал ссылки из файла, я забыл удалить символ новой строки, и из-за этого все они вернули 200. Отличный ответ, спасибо - person Scherf; 03.03.2014
comment
@Scherf: urls в коде уже является списком URL-адресов (подойдет любой итерируемый объект). Вы имеете в виду, как прочитать этот список из файла: urls = [line.strip() for line in open('filename') if line.strip()] - person jfs; 03.03.2014

Итак, вот простой способ сделать это:

import httplib2
h = httplib2.Http(".cache")
resp, content = h.request("http://www.python.org/", "GET")
print content

Источник: https://code.google.com/p/httplib2/wiki/Examples

person Sharif Mamun    schedule 02.03.2014