Я довольно новичок в python, и я надеюсь, что кто-то здесь может мне помочь.Пул многопроцессорности Python замерзает без причины
Я начал изучать python несколько недель назад, и я попытался создать webcrawler.
Идея такова: первая часть обходит домены с сайта (для каждой буквы). Вторая часть проверяет, действителен ли домен (доступен и не припаркован), и сохраняется в базе данных.
Все идет хорошо, пока гусеничный ход не достигнет «r». Через несколько минут программа зависает без каких-либо сообщений об ошибках и т. Д. Также буквы после «r» не создают никаких проблем ... Домен, где программа зависает, не то же самое.
Вот мой код:
import requests
import re
import logging
import time
from bs4 import BeautifulSoup
from multiprocessing.pool import Pool
""" Extract only the plain text of element
"""
def visible(element):
if element.parent.name in ['style', 'script', '[document]', 'head', 'title']:
return False
elif re.match('.*<!--.*-->.*', str(element), re.DOTALL):
return False
elif re.fullmatch(r"[\s\r\n]", str(element)):
return False
return True
logging.basicConfig(format='%(asctime)s %(name)s - %(levelname)s: %(message)s', level=logging.ERROR)
logger = logging.getLogger('crawler')
hdlr = logging.FileHandler('crawler.log')
formatter = logging.Formatter('%(asctime)s %(name)s - %(levelname)s: %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.DEBUG)
""" Checks if a domain is parked.
Returns true if a domain is not parked, otherwise false
"""
def check_if_valid(website):
try:
resp = requests.get("http://www." + website, timeout=10, verify=False)
soup = BeautifulSoup(resp.text, 'html.parser')
if len(soup.find_all('script')) == 0:
# check for very small web pages
if len(resp.text) < 700:
return None
# check for 'park' pattern
text = filter(visible, soup.find_all(text=True))
for elem in text:
if 'park' in elem:
return None
return "http://www." + website + "/"
except requests.exceptions.RequestException as e:
# no logging -> too many exceptions
return None
except Exception as ex:
logger.exception("Error during domain validation")
def persist_domains(nonParkedDomains):
logger.info("Inserting domains into database")
dbConn = mysqlDB.connect()
for d in nonParkedDomains:
mysqlDB.insert_company_domain(dbConn, d)
mysqlDB.close_connection(dbConn)
if __name__ =="__main__":
dryrun = True
if dryrun:
logger.warning("Testrun! Data does not get persisted!")
url = "http://www.safedomain.at/"
# chars = ['0-9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u', 'v', 'w', 'x', 'y', 'z']
chars = ['r','s', 't','u', 'v', 'w', 'x', 'y', 'z']
payload = {'sub': 'domains', 'char': '', 'page': '1'}
domains = list()
cntValidDomains = 0
logger.info("Start collecting domains from \"http://www.safedomain.at\"....")
try:
for c in chars:
payload['char'] = c
payload['page'] = '1'
response = requests.get(url, params=payload, verify=False)
soup = BeautifulSoup(response.text, 'html.parser')
while not soup.find_all('a', {'data-pagenumber': True}):
time.sleep(5)
response = requests.get(url, params=payload, verify=False)
soup = BeautifulSoup(response.text, 'html.parser')
maxPage = int(soup.find_all('a', {'data-pagenumber': True})[-1].getText())
domains = list()
for page in range(1, maxPage + 1):
payload['page'] = page
logger.debug("Start crawling with following payload: char=%s page=%s", payload['char'], payload['page'])
response = requests.get(url, params=payload)
soup = BeautifulSoup(response.text, 'html.parser')
for elem in soup.find_all('ul', {'class': 'arrow-list'}):
for link in elem.find_all('a'):
domains.append(link.getText())
logger.info("Finished! Collected domains for %s: %s",c, len(domains))
logger.info("Checking if domains are valid...")
with Pool(48) as p:
nonParkedDomains = p.map(check_if_valid, domains)
p.close()
p.join()
nonParkedDomains = list(filter(None.__ne__, nonParkedDomains))
cntTemp = cntTemp + len(nonParkedDomains)
# check if domains should get persisted
if dryrun:
logger.info("Valid domains for %s in domains", c)
for elem in nonParkedDomains:
logger.info(elem)
else:
persist_domains(nonParkedDomains)
logger.info("Finished domain validation for %s!", c)
cntValidDomains = cntTemp + cntValidDomains
logger.info("Valid domains: %s", cntTemp)
logger.info("Program finished!")
except Exception as e:
logger.exception("Domain collection stopped unexpectedly")
EDIT: После нескольких часов отладки и тестирования у меня есть идея. Может ли быть, что модуль запросов, который используется в потоке, вызывает проблемы?
я уже нашел подобную проблему здесь: [ссылка] (http://stackoverflow.com/questions/19071529/python-multiprocessing-125-list-never-finishes) Но программа останавливается в потоке пул и даже не доходит до линии, где я закрываю и присоединяюсь к пулу. – mLe