-2

Привет, ребята, я довольно новичок в python. что я пытаюсь сделать, это переместить мой старый код в многопроцессорную, однако я столкнулся с некоторыми ошибками, которые, я надеюсь, кто-нибудь сможет мне помочь. Мой код используется для проверки нескольких тысяч ссылок, указанных в текстовой форме, для проверки определенных тегов. Найдя, он выведет его мне. Из-за того, что у меня есть несколько тысяч ссылок для проверки, скорость - это проблема, и поэтому мне нужно переходить на многопроцессорную обработку.Многопроцессорство в проблемах python/beautifulsoup

Обновление: у меня возникают ошибки HTTP 503 ошибок. Я посылаю слишком много запросов или у меня что-то упущено?

Multiprocessing код:

from mechanize import Browser 
from bs4 import BeautifulSoup 
import sys 
import socket 
from multiprocessing.dummy import Pool # This is a thread-based Pool 
from multiprocessing import cpu_count 

br = Browser() 
br.set_handle_robots(False) 
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] 

no_stock = [] 

def main(lines): 
    done = False 
    tries = 1 
    while tries and not done: 
     try: 
      r = br.open(lines, timeout=15) 
      r = r.read() 
      soup = BeautifulSoup(r,'html.parser') 
      done = True # exit the loop 
     except socket.timeout: 
      print('Failed socket retrying') 
      tries -= 1 # to exit when tries == 0 
     except Exception as e: 
      print '%s: %s' % (e.__class__.__name__, e) 
      print sys.exc_info()[0] 
      tries -= 1 # to exit when tries == 0 
    if not done: 
     print('Failed for {}\n'.format(lines)) 
    table = soup.find_all('div', {'class' : "empty_result"}) 
    results = soup.find_all('strong', style = 'color: red;') 
    if table or results: 
     no_stock.append(lines) 

if __name__ == "__main__": 
    r = br.open('http://www.randomweb.com/') #avoid redirection 
    fileName = "url.txt" 
    pool = Pool(processes=2) 
    with open(fileName, "r+") as f: 
     lines = pool.map(main, f) 
    with open('no_stock.txt','w') as f : 
     f.write('No. of out of stock items : '+str(len(no_stock))+'\n'+'\n') 
    for i in no_stock: 
     f.write(i + '\n') 

Traceback:

Traceback (most recent call last): 
    File "test2.py", line 43, in <module> 
    lines = pool.map(main, f) 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map 
    return self.map_async(func, iterable, chunksize).get() 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 567, in get 
    raise self._value 
UnboundLocalError: local variable 'soup' referenced before assignment 

мой текстовый файл что-то вроде этого: -

http://www.randomweb.com/item.htm?uuid=44733096229 
http://www.randomweb.com/item.htm?uuid=4473309622789 
http://www.randomweb.com/item.htm?uuid=447330962291 
....etc 
+1

Вам нужно добавить свои трассировочные (-е) следы после. –

+0

Привет, Морган, спасибо за ответ, но я не совсем понимаю ваш смысл. Не могли бы вы объяснить больше? – Jeof

+0

Вам нужно добавить, чтобы добавить ошибки, которые вы получаете на свой основной пост. –

ответ

-1
from mechanize import Browser 
from bs4 import BeautifulSoup 
import sys 
import socket 
from multiprocessing.dummy import Pool # This is a thread-based Pool 
from multiprocessing import cpu_count 

br = Browser() 

no_stock = [] 

def main(line): 
    done = False 
    tries = 3 
    while tries and not done: 
     try: 
      r = br.open(line, timeout=15) 
      r = r.read() 
      soup = BeautifulSoup(r,'html.parser') 
      done = True # exit the loop 
     except socket.timeout: 
      print('Failed socket retrying') 
      tries -= 1 # to exit when tries == 0 
     except: 
      print('Random fail retrying') 
      print sys.exc_info()[0] 
      tries -= 1 # to exit when tries == 0 
    if not done: 
     print('Failed for {}\n'.format(i)) 
    table = soup.find_all('div', {'class' : "empty_result"}) 
    results = soup.find_all('strong', style = 'color: red;') 
    if table or results: 
     no_stock.append(i) 

if __name__ == "__main__": 
    fileName = "url.txt" 
    pool = Pool(cpu_count() * 2) # Creates a Pool with cpu_count * 2 threads. 
    with open(fileName, "rb") as f: 
     lines = pool.map(main, f) 
    with open('no_stock.txt','w') as f : 
     f.write('No. of out of stock items : '+str(len(no_stock))+'\n'+'\n') 
    for i in no_stock: 
     f.write(i + '\n') 

pool.map принимает два параметра, то fist - это функция (в вашей команде de, является основным), другой - итерируемым, каждый элемент итерабельного будет параметром функции (в вашем коде - каждая строка файла)

+0

спасибо за советы, я сделал abit исправления для итерации на других частях, однако код, похоже, не работает. он дает мне error – Jeof

+0

вы можете разместить полную информацию о трассировке – Hooting

+0

, почему вам нужно tqdm? значение строк, переданных в main, - это одна строка файла, которая отвечает на веб-сайт, поэтому вы можете просто использовать «строки» для браузера. – Hooting