0

미리 도움을 주셔서 감사합니다. 저는 Python에 익숙하지 않고 스레딩 모듈을 사용하여 NY Daily News 사이트에서 URL을 긁어 모으려고합니다. 나는 다음을 함께 쓰고 스크립트는 폐기하고 있지만 이전보다 빠르지는 않은 것 같아서 스레딩이 발생하고 있는지 잘 모르겠습니다. 그게 있으면 알려주실 수 있습니까? 내가 말할 수 있도록 쓸 수 있을까요? 또한 스레딩에 대한 다른 팁도 있습니다.이것은 실제로 URL을 긁어 내기 위해 스레딩을 사용하고 있습니까?

감사합니다.

from bs4 import BeautifulSoup, SoupStrainer 
import urllib2 
import os 
import io 
import threading 

def fetch_url(): 
    for i in xrange(15500, 6100, -1): 
     page = urllib2.urlopen("http://www.nydailynews.com/search-results/search-results-7.113?kw=&tfq=&afq=&page={}&sortOrder=Relevance&selecturl=site&q=the&sfq=&dtfq=seven_years".format(i)) 
     soup = BeautifulSoup(page.read()) 
     snippet = soup.find_all('h2') 
     for h2 in snippet: 
      for link in h2.find_all('a'): 
       logfile.write("http://www.nydailynews.com" + link.get('href') + "\n") 
     print "finished another url from page {}".format(i) 

with open("dailynewsurls.txt", 'a') as logfile: 
    threads = threading.Thread(target=fetch_url()) 
    threads.start() 
+0

몇 개의 URL을 긁으려고합니까? NYDN이 자신의 사이트에서 500 개 이상의 병렬 요청을 실행하고 싶다고 생각합니까? –

+0

이 코드는 ** 하나의 스레드 ** (메인 스레드 제외)를 사용하여 URL을 긁습니다. 그건 도움이되지 않을거야. URL 당 별도의 스레드 * 사용 *. –

+3

URL 당 별도의 스레드를 사용하여 긁어 모으는 경우 로그 파일에 쓰기 위해 일종의 잠금을 구현해야합니다. 일종의 동시성 제어없이 별도의 스레드에서 파일에 쓸 수는 없습니다. "프로그래머가 문제를 겪었습니다."그는 프로그래머가 문제가 있다고 생각했는데, '실감 난다. 실감 난다. 문제가있다.'* –

답변

2

아래는 (매우 빠르게 nydailynews.com에서 블랙리스트에 얻을 것이다) 순진 구현 : fetch_url 인수로 URL에 대체 할 수 소요

def fetch_url(i, logfile): 
    page = urllib2.urlopen("http://www.nydailynews.com/search-results/search-results-7.113?kw=&tfq=&afq=&page={}&sortOrder=Relevance&selecturl=site&q=the&sfq=&dtfq=seven_years".format(i)) 
    soup = BeautifulSoup(page.read()) 
    snippet = soup.find_all('h2') 
    for h2 in snippet: 
     for link in h2.find_all('a'): 
      logfile.write("http://www.nydailynews.com" + link.get('href') + "\n") 
    print "finished another url from page {}".format(i) 

with open("dailynewsurls.txt", 'a') as logfile: 
    threads = [] 
    for i in xrange(15500, 6100, -1): 
     t = threading.Thread(target=fetch_url, args=(i, logfile)) 
     t.start() 
     threads.append(t) 
    for t in threads: 
     t.join() 

하는 것으로하고, 그 인수에 대한 각 가능한 값은 별도의 스레드에서 시작됩니다.

나는 강력하게으로 작업을 작은 배치로 나누고 한 번에 하나의 배치를 실행하는 것이 좋습니다.

+1

나는 http://www.nydailynews.com에 앉아있는 바니시에 오목면을 만들기 전에 OP가 자신의 시스템 자원을 먼저 굶어 죽일 것이라고 확신합니다. –

+0

감사합니다 !! 이상하게도 파일과 모든 것에 인쇄하는 것은 잘되고 있습니다. ValueError : 닫힌 파일에 대한 입출력 작업 –

+0

@JolijtTamanaha,'with' 절의 'exit' 부분이 실행 중이기 때문에 발생한다고 생각합니다. 모든 스레드가 종료 된 후에가 아니라 모든 스레드가 시작된 후에 't.join()'을 그 절로 옮기므로 모든 스레드가 종료 될 때까지 로그 파일을 닫지 마십시오. –

1

아니요, 스레드를 사용하고 있지 않습니다. threads = threading.Thread(target=fetch_url())은 주 스레드에서 fetch_url()을 호출하고 은 완료 될 때까지 대기하고의 반환 값 (None)을 threading.Thread 생성자로 전달합니다.

+0

사실 질문에 대한 답변입니다. 유능한. :) –

관련 문제