Это мое решение из теста на вакансию задача.
Совершенно не уверен, правильно ли я понял задачу, но вот мое решение. Примечание: в настоящее время код неверен
Код:
import asyncio
import aiohttp
from sys import exit as sys_exit
from bs4 import BeautifulSoup
import timeit
def is_item_exist(dict_key: str, array: list):
"""
The only way I found to check if dict key is in a list
"""
for i, dict_ in enumerate(array):
if dict_['form_number'] == dict_key:
return i
async def load_pages():
shift = 0 # To iterate over pages (pagination)
pages = []
url = (f'https://apps.irs.gov/app/picklist/list/priorFormPublication.html?'
f'indexOfFirstRow={shift}&sortColumn=sortOrder&value=&criteria=&resultsPerPage=200&isDescending=false')
async with aiohttp.ClientSession() as session:
for shift in range(10):
async with session.get(url=url) as resp:
if 200 <= resp.status <= 299:
await resp.text()
pages.append(resp.text())
shift += 200 # 200 rows per page
else:
print('Cant access a page')
sys_exit(1)
return pages
def parse_pages(pages):
pages_forms = [] # Result
for page in pages:
soup = BeautifulSoup(page.content, 'html.parser')
table = soup.find(name="table", attrs={'class': 'picklist-dataTable'})
rows = table.find_all(name="tr")[1:]
page_forms = []
for row in rows:
form_number = row.findChild(['LeftCellSpacer', 'a']).string.split(' (', 1)[0] # Remove non eng versions of forms
current_year = int(row.find(name="td", attrs={'class': 'EndCellSpacer'}).string.strip())
index = is_item_exist(dict_key=form_number, array=page_forms)
if index is not None:
if page_forms[index]['min_year'] > current_year:
page_forms[index]['min_year'] = current_year
# print('changed')
elif page_forms[index]['max_year'] < current_year:
page_forms[index]['max_year'] = current_year
# print('changed')
else:
form_title = row.find(name="td", attrs={'class': 'MiddleCellSpacer'}).string.strip()
page_forms.append({
'form_number': form_number,
'form_title': form_title,
'min_year': current_year,
'max_year': current_year,
})
pages_forms.append(page_forms)
return pages_forms
def main():
return parse_pages(load_pages())
if __name__ == '__main__':
start = timeit.default_timer()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
print(timeit.default_timer() - start)
Ошибка:
line 36, in parse_pages
for page in pages:
TypeError: 'coroutine' object is not iterable
Вопросов:
- Я выбрал хорошую архитектуру? Особенно мне любопытно самореализация
if item not in listpython, потому что в основном этот шаблон хорош для простого объекта внутри списка, но у меня есть списокdicts и проверкаdictключ. После некоторых экспериментов я не нашел лучшего воплощения, чем представленный здесь. - Достаточно ли асинхронного решения? Это мой первый опыт асинхронного удаления веб-страниц.
- Может быть, нужно оптимизировать проверку, существует ли форма в списке форм и не перебирать каждый раз весь список, а применить какой-то алгоритм сортировки или что-то еще?
![асинхронное удаление веб-страниц в Python [closed] TheFAQ.ru](https://thefaq.ru/wp-content/uploads/2023/01/logo-250.png)