2014-11-20 4 views
-1

URL을 사용하여 페이지의 <title> 태그 값을 반환하는 스크립트가 있습니다. 몇 백 정도 실행 후, 나는 항상 같은 오류가 발생합니다 :왜 httplib2.RedirectLimit 오류가 발생합니까?

def get_title(pageurl): 
    http = httplib2.Http() 
    status, response = http.request(pageurl) 
    x = BeautifulSoup(response, parseOnlyThese=SoupStrainer('title')) 
    x = str(x) 
    y = x[7:-8] 
    z = y.split('-')[0] 
    return z 

매우 간단합니다 :

File "/home/edmundspenser/Dropbox/projects/myfiles/titlegrab.py", line 202, in get_title 
    status, response = http.request(pageurl) 
File "/usr/lib/python2.7/dist-packages/httplib2/__init__.py", line 1390, in _request 
    raise RedirectLimit("Redirected more times than rediection_limit allows.", response, content) 
httplib2.RedirectLimit: Redirected more times than rediection_limit allows. 

내 기능은 같다. 내가 tryexcepttime.sleep(1)을 사용하여 문제가된다면 아무런 문제가 없을 수도 있지만 아직까지는 아무런 효과가 없었습니다. 그리고 나는 그것에 pass 싶지 않아요. 어쩌면 웹 사이트가 속도를 제한하고 있을까요?

편집 : 지금 스크립트는 전혀 작동하지 않으며 첫 번째 요청과 함께 오류가 발생합니다.

www.wikiart.org 페인팅 페이지의 URL이 80,000 개 이상인 json 파일이 있습니다. 각자를 위해 나는 나의 직책을 수행하여 직함을 얻는다. 그래서 :

print repr(get_title('http://www.wikiart.org/en/vincent-van-gogh/van-gogh-s-chair-1889')) 

반환

"Van Gogh's Chair" 
+1

코드가 작동하는지 확인하려면 다른 웹 사이트에서 코드를 사용하십시오. 그렇다면 사이트가 속도 제한을 설정합니다. – KooKoo

+0

그들이 나를 속도를 제한한다고 가정 해 봅시다. 속도를 늦추어 서 가능한 한 빨리 갈 수있는 방법을 찾는 방법은 무엇입니까? 각 URL에 대해 새로운 URL을 보내는 대신 하나의 http 요청을 더 많이 얻을 수있는 방법이 있습니까? –

+1

액세스하려는 URL을 지정할 수 있습니까? – Manhattan

답변

2

Requests 라이브러리를 사용해보십시오. 결국, 내가 본 속도 제한이없는 것 같습니다. 21.6 초에 13 곡을 검색 할 수있었습니다. 아래를 참조

코드 :

import requests as rq 
from bs4 import BeautifulSoup as bsoup 

def get_title(url): 

    r = rq.get(url) 
    soup = bsoup(r.content) 
    title = soup.find_all("title")[0].get_text() 
    print title.split(" - ")[0] 

def main(): 

    urls = [ 
    "http://www.wikiart.org/en/henri-rousseau/tiger-in-a-tropical-storm-surprised-1891", 
    "http://www.wikiart.org/en/edgar-degas/the-green-dancer-1879", 
    "http://www.wikiart.org/en/claude-monet/dandelions", 
    "http://www.wikiart.org/en/albrecht-durer/the-little-owl-1506", 
    "http://www.wikiart.org/en/gustav-klimt/farmhouse-with-birch-trees-1903", 
    "http://www.wikiart.org/en/jean-michel-basquiat/boxer", 
    "http://www.wikiart.org/en/fernand-leger/three-women-1921", 
    "http://www.wikiart.org/en/alphonse-mucha/flower-1897", 
    "http://www.wikiart.org/en/alphonse-mucha/ruby", 
    "http://www.wikiart.org/en/georges-braque/musical-instruments-1908", 
    "http://www.wikiart.org/en/rene-magritte/the-evening-gown-1954", 
    "http://www.wikiart.org/en/m-c-escher/lizard-1", 
    "http://www.wikiart.org/en/johannes-vermeer/the-girl-with-a-pearl-earring" 
    ] 

    for url in urls: 
     get_title(url) 

if __name__ == "__main__": 
    main() 

출력은 :

Tiger in a Tropical Storm (Surprised!) 
The Green Dancer 
Dandelions 
The Little Owl 
Farmhouse with Birch Trees 
Boxer 
Three Women 
Flower 
Ruby 
Musical Instruments 
The evening gown 
Lizard 
The Girl with a Pearl Earring 
[Finished in 21.6s] 

그러나, 개인 윤리에서, 나는 이런 식으로 일을하지 않는 것이 좋습니다. 빠른 연결을 사용하면 데이터를 너무 빨리 가져옵니다. 긁힌 자국이 20 초마다 잠들도록 허용하면 몇 초 동안 다 치지 않아도됩니다.

EDIT : 비동기 요청을 허용하는 grequests을 사용하는 더 빠른 버전입니다. 위의 동일한 데이터를 2.6 초 동안 끌어 올리면 거의 10 배 더 빠릅니다. 다시 사이트에 대한 존경심에서 스크래핑 속도가 제한됩니다..

import grequests as grq 
from bs4 import BeautifulSoup as bsoup 

def get_title(response): 

    soup = bsoup(response.content) 
    title = soup.find_all("title")[0].get_text() 
    print title.split(" - ")[0] 

def main(): 

    urls = [ 
    "http://www.wikiart.org/en/henri-rousseau/tiger-in-a-tropical-storm-surprised-1891", 
    "http://www.wikiart.org/en/edgar-degas/the-green-dancer-1879", 
    "http://www.wikiart.org/en/claude-monet/dandelions", 
    "http://www.wikiart.org/en/albrecht-durer/the-little-owl-1506", 
    "http://www.wikiart.org/en/gustav-klimt/farmhouse-with-birch-trees-1903", 
    "http://www.wikiart.org/en/jean-michel-basquiat/boxer", 
    "http://www.wikiart.org/en/fernand-leger/three-women-1921", 
    "http://www.wikiart.org/en/alphonse-mucha/flower-1897", 
    "http://www.wikiart.org/en/alphonse-mucha/ruby", 
    "http://www.wikiart.org/en/georges-braque/musical-instruments-1908", 
    "http://www.wikiart.org/en/rene-magritte/the-evening-gown-1954", 
    "http://www.wikiart.org/en/m-c-escher/lizard-1", 
    "http://www.wikiart.org/en/johannes-vermeer/the-girl-with-a-pearl-earring" 
    ] 

    rs = (grq.get(u) for u in urls) 
    for i in grq.map(rs): 
     get_title(i) 

if __name__ == "__main__": 
    main() 
+0

요청 메서드가 마음에 들지만 사용하고 있지만 비슷한 오류가 발생합니다. 'requests.exceptions.TooManyRedirects : 30 redirects. Exceeded를 초과합니다.'이 오류가 발생하기 전에 짧은 시간 내에 내 코드가 거의 50,000 개의 title-url 쌍을 완료했습니다 , 그래서 나는 다소 기분이 좋고, 내가 그들을 늪에 빠뜨리는데 제한적 이었는지 이해한다. –

+1

그러면 일시적인 금지 조치 일 수 있습니다. 거의 모든 큰 사이트에는 긁어 모으지 않도록 일종의 방어가 있습니다. Wikimedia가 그들의 사이트를 위해 그것을 가지고 있다면 놀라지 않을 것입니다. – Manhattan

+0

나는 오늘 밤이나 내일까지 코드를 보류 할 것이다. 루프를 위해 한 번에 하나씩 업그레이드를 찾고 있었기 때문에'grequests '를 사용하기를 고대하고 있습니다. –