Advertisement
andreymal

https://ru.stackoverflow.com/questions/1421077

Jun 17th, 2022
913
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.40 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import asyncio
  4. import itertools
  5. import json
  6. import random
  7. import time
  8. from typing import List
  9.  
  10. import aiohttp
  11. from bs4 import BeautifulSoup
  12. from fake_useragent import UserAgent
  13.  
  14.  
  15. def abs_url(url: str) -> str:
  16.     # Преобразует относительный URL в абсолютный
  17.     if url.startswith("//"):
  18.         return f"https:{url}"
  19.     if url.startswith("/"):
  20.         return f"https://069.net.ua{url}"
  21.     return url
  22.  
  23.  
  24. async def get_page_items(session: aiohttp.ClientSession, semaph: asyncio.Semaphore, page_url: str) -> List[str]:
  25.     page_items_list: List[str] = []
  26.  
  27.     async with semaph:
  28.         async with session.get(page_url) as resp:
  29.             page_src = await resp.text(errors="replace")
  30.  
  31.         page_soup = BeautifulSoup(page_src, "lxml")
  32.         header = page_soup.find("h1").text
  33.  
  34.         current_page = page_soup.find(class_="pgsn").text
  35.         itemslist = page_soup.findAll(class_="desc")
  36.         for el in itemslist:
  37.             page_items_list.append(abs_url(el.a.get("href")))
  38.  
  39.         print(f"{header} {current_page} done")
  40.         await asyncio.sleep(random.randint(1, 3))
  41.  
  42.     return page_items_list
  43.  
  44.  
  45. async def get_item_content(session: aiohttp.ClientSession, semaph: asyncio.Semaphore, item_url: str) -> None:
  46.     async with semaph:
  47.         await asyncio.sleep(random.randint(1, 3))
  48.  
  49.         async with session.get(item_url) as resp:
  50.             itempage_src = await resp.text(errors="replace")
  51.  
  52.         page_soup = BeautifulSoup(itempage_src, "lxml")
  53.  
  54.         item_name = page_soup.find("h1").text
  55.         item_code = page_soup.find_all(class_="g-r")[-2].text
  56.         photo_link = abs_url(page_soup.find(id="s-gal-bp").img.get("src"))
  57.         item_color = page_soup.find_all(class_="g-r")[-2].text
  58.  
  59.         size_list: List[str] = []
  60.         for item in page_soup.find_all("option"):
  61.             if item.text != "Виберіть":
  62.                 size_list.append(item.text)
  63.  
  64.         item_category = page_soup.find_all(itemprop="name")[1].text
  65.         try:
  66.             item_price = page_soup.find(class_="prcn").text
  67.         except Exception:
  68.             item_price = "no name"
  69.  
  70.         item_availability = "В наявності" if size_list else "Відсутній"
  71.  
  72.         item_brand = page_soup.find_all(itemprop="name")[2].text
  73.  
  74.         print()
  75.         print("===========================================")
  76.         print(f"назва товару - {item_name}")
  77.         print(f"код товару - {item_code}")
  78.         print(f"посилання на фото товару - {photo_link}")
  79.         print(f"колір - {item_color}")
  80.         print(f"розміри- {size_list}")
  81.         print(f"категорія - {item_category}")
  82.         print(f"ціна - {item_price}")
  83.         print(f"наявність - {item_availability}")
  84.         print(f"бренд - {item_brand}")
  85.         print("===========================================")
  86.  
  87.         with open(f"try/{time.time()}.html", "w", encoding="utf-8") as file:
  88.             file.write(itempage_src)
  89.  
  90.         await asyncio.sleep(random.randint(7, 11))
  91.  
  92.  
  93. async def main() -> None:
  94.     headers = {"User-Agent": UserAgent().random}
  95.     connector = aiohttp.TCPConnector(limit=30)
  96.     session = aiohttp.ClientSession(headers=headers, connector=connector)
  97.  
  98.     async with session:
  99.         # Получаем список категорий из шапки сайта
  100.         async with session.get(abs_url("/ua/")) as resp:
  101.             indexpage_src = await resp.text(errors="replace")
  102.  
  103.         categories_soup = BeautifulSoup(indexpage_src, "lxml").find(id="tabs")
  104.         categories_list = categories_soup.find_all(class_="sta")
  105.         category_dict = {}
  106.  
  107.         for category in categories_list:
  108.             category_dict[category.text] = abs_url(category["href"])
  109.  
  110.         with open("files/Categories.json", "w", encoding="utf-8") as file:
  111.             json.dump(category_dict, file, indent=4, ensure_ascii=False)
  112.  
  113.         # Собираем ссылки на все страницы всех категорий
  114.         all_pages_list: List[str] = []
  115.  
  116.         for name, url in category_dict.items():
  117.             await asyncio.sleep(1)
  118.             async with session.get(url) as resp:
  119.                 categorypage_src = await resp.text(errors="replace")
  120.  
  121.             pagination_links = BeautifulSoup(categorypage_src, "lxml").find(id="flt-opt").find_all(class_="pgs")
  122.             last_pageno = int(pagination_links[-2].text.strip())
  123.             for pageno in range(1,last_pageno + 1):
  124.                 all_pages_list.append(f"{url}?page={pageno}/")
  125.             print(f"{name} done")
  126.  
  127.         # Собираем ссылки на все товары со всех страниц
  128.         # Скорость сбора ограничиваем семафором
  129.         semaph = asyncio.Semaphore(15)
  130.         tasks = [
  131.             asyncio.create_task(get_page_items(session, semaph, page_url))
  132.             for page_url in all_pages_list
  133.         ]
  134.         all_items_list = itertools.chain(*await asyncio.gather(*tasks))
  135.  
  136.         # И теперь скачиваем все товары
  137.         tasks = [
  138.             asyncio.create_task(get_item_content(session, semaph, item_url))
  139.             for item_url in all_items_list
  140.         ]
  141.         await asyncio.gather(*tasks)
  142.  
  143.     print("Finished!")
  144.  
  145.  
  146. if __name__ == "__main__":
  147.     asyncio.run(main())
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement