#python #multithreading #web-scraping #python-requests #pool
#python #многопоточность #веб-очистка #python-запросы #Бассейн
Вопрос:
Ниже приведен код, который я использую для очистки своих данных и сохранения их в виде файла pickle. Для ссылок, по которым возвращается ошибка, код просто записывает URL-адрес и добавляет его в другой список, чтобы я мог очистить их снова.
data= []
failed_url = []
error =[]
start = time.asctime( time.localtime(time.time()) )
# list_url is a list containing all urls
for path in list_url:
try:
headers = {'Content-Type': 'application/json'}
filters = [dict(source_location="petitions_browse")]
params = dict(q=json.dumps(dict(filters=filters)))
result = requests.get(url=path,params=params)
time.sleep(5)
data_dict = result.json()
data.append({
'Data_dict': data_dict,
'id': data_dict['id'],
'title': data_dict['title'],
'text': data_dict['description'],
'Topic': data_dict['topic'],
'Topic_alt': data_dict['tags'][0]['name'],
'Created_date': data_dict['created_at'].split("T")[0],
'Created_time': data_dict['created_at'].split("T")[1],
})
time.sleep(5)
except Exception as e:
print(e)
error.append(e)
failed_url.append(path)
continue
if len(data)%50 == 0:
pickle.dump(data, open("data_checkpoint" ".pkl", "wb"))
pickle.dump(data, open("data" ".pkl", "wb"))
pickle.dump(failed_url, open("failed_url" ".pkl", "wb"))
end = time.asctime( time.localtime(time.time()) )
print('start time:', start, 'end time:', end)
print('Failed Links:', failed_url)
Я адаптирую его для многопроцессорной обработки, используя следующий код:
def get_data(url):
try:
headers = {'Content-Type': 'application/json'}
filters = [dict(source_location="petitions_browse")]
params = dict(q=json.dumps(dict(filters=filters)))
result = requests.get(url=url,params=params)
data_dict = result.json()
return{
'Data_dict': data_dict,
'id': data_dict['id'],
'title': data_dict['title'],
'text': data_dict['description'],
'Topic': data_dict['topic'],
'Topic_alt': data_dict['tags'][0]['name'],
'Created_date': data_dict['created_at'].split("T")[0],
'Created_time': data_dict['created_at'].split("T")[1],
}
#time.sleep(5)
except Exception as e:
print(e)
try:
return {'Data_dict': data_dict}
except Exception as c:
return("failed_url", path)
#continue
with Pool(10) as pool:
result = pool.map(get_data, url_list)
print(result)
failed_url,data=[],[]
for res in result:
if isinstance(res,tuple):
failed_url.append(res[1])
else:
data.append(res)
pickle.dump(data, open("data" ".pkl", "wb"))
pickle.dump(failed_url, open("failed_url_test" ".pkl", "wb"))
Похоже, что эта адаптация не выполняется. Для небольшого количества ссылок он продолжает работать в течение длительного времени, и, таким образом, кажется, что с этим есть проблема, потому что для того же количества ссылок код без многопоточности выполняется быстрее.
Комментарии:
1.
map
Когда-нибудь возвращается? «похоже, что не выполняется» немного расплывчато.2. Я буду рекомендовать использовать
scrapy
фреймворк, он прост в использовании, и вы можете настроить его на использование mt-запросов3. Если вы действительно хотите добиться параллелизма при выполнении запросов, я рекомендую
aiohttp
. Он используетasyncio
под капотом, и это, вероятно, будет быстрее, чем многопоточность и мультиобработка сrequests
. Документы: docs.aiohttp.org/en/stable4. Также обратите внимание, что вы делаете широкий охват всех
Exeption
, что является плохим. В этом случае, если какая-либо из первых четырех строк в функции вызовет исключение, будет введенexcept
блок, которыйdata_dict
вызоветNameError
, потому что он еще не был установлен. Поскольку вы не упоминаете ошибку, похоже, что проблема здесь не в этом. Я бы все равно знал об этом.5. @Carcigenicate Я отредактировал перехват исключения. Я думаю, это должно исправить то, о чем вы говорите!