查看: 478|回复: 0

[电脑应用] [Python] 【异步爬虫】无聊的小爬虫,大家一起学习

[复制链接]
累计签到:390 天
连续签到:2 天

53

主题

134

回帖

6823

积分

域主

名望
236
星币
4323
星辰
7
好评
35

欢乐天使奖灌水天才奖鼎力支持奖幸运猪星辰勋章优秀会员奖明星会员奖魅力会员奖国庆节勋章在线大神

QQ
发表于 2022-8-6 14:25:20 | 显示全部楼层 |阅读模式

注册登录后全站资源免费查看下载

您需要 登录 才可以下载或查看,没有账号?立即注册

×
【成品下载地址】链接: https://pan.baidu.com/s/1Pz4C0m-SaoqdGz2XWTit6Q?pwd=d4q6 提取码: d4q6

【成品下载地址】链接:https://share.weiyun.com/WeRMZ25w 密码:82jtk5

无聊随便写的,供大家学习吧~,希望有大佬帮我改进一下,我觉得还是代码有点

  1. # //div[@class="item_list infinite_scroll masonry"]/div[num]//a/img/@alt 壁纸标题
  2. # //div[@class="item_list infinite_scroll masonry"]/div[num]//a/img/@href 壁纸图片地址
  3. # 总页数440页 [url=https://www.mmonly.cc/gqbz/list_41_]https://www.mmonly.cc/gqbz/list_41_[/url][num].html 页数num从1开始到440
  4. # //div[@class="topmbx"]/a[last()]/text() 壁纸类型
  5. # //div[@id="big-pic"]//a/@href 壁纸高清地址


  6. import aiofiles
  7. import aiohttp
  8. import asyncio
  9. import async_timeout
  10. from collections import namedtuple
  11. import time
  12. import os
  13. from rich.console import Console
  14. from fake_useragent import UserAgent
  15. from lxml import etree
  16. from typing import List,Text
  17. from datetime import datetime
  18. import keyboard
  19. from threading import Thread

  20. console = Console()
  21. headers = {'User-Agent':UserAgent().random}
  22. Img_url_name = namedtuple('Img_url_name', ['img_url', 'img_name'])
  23. Img_big_url_type = namedtuple('Img_big_url_name', ['img_big_url', 'img_type'])
  24. sign = True # 信号


  25. async def get_html(url) -> Text:
  26.     """
  27.     获取网页源码
  28.     """
  29.     async with aiohttp.ClientSession() as session:
  30.         async with async_timeout.timeout(10):
  31.             async with session.get(url) as resp:           
  32.                 return await resp.text()



  33. async def save_img(img_url,path,img_name) -> None:
  34.     """
  35.     保存图片
  36.     """
  37.     async with aiohttp.ClientSession() as session:
  38.         async with async_timeout.timeout(10):
  39.             async with session.get(img_url,headers=headers) as resp:
  40.                 img = await resp.read()
  41.                 async with aiofiles.open(f'{path}\{img_name}', 'wb') as f:
  42.                     await f.write(img)
  43.                     nowtime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  44.                     console.print(f'[yellow]创建时间:{nowtime}\n保存路径:{os.path.join(os.getcwd(),path)}\n文件名称:{img_name}\n状态:[green]下载完成!\n[gray]提示:按esc退出')
  45.                     console.print('[blue]-'*50)

  46. def get_img_url_name(resp_text) -> List:
  47.     """
  48.     获取缩略图页面的图片地址和图片名称
  49.     """
  50.     tree = etree.HTML(resp_text)
  51.     # 每页有24张缩略图和网址
  52.     img_url_name = [Img_url_name(img_url = tree.xpath(f'//div[@class="item_list infinite_scroll masonry"]/div[{num}]//a/@href')[0],
  53.     img_name = tree.xpath(f'//div[@class="item_list infinite_scroll masonry"]/div[{num}]//a/img/@alt')[0]) for num in range(1,25)]
  54.     return img_url_name

  55. def get_big_img(resp_text) -> Img_big_url_type:
  56.     """
  57.     获取详情页的高清图片地址和图片类型
  58.     """
  59.     tree = etree.HTML(resp_text)
  60.     img_big_url = tree.xpath('//div[@id="big-pic"]//a/img/@src')[0] if tree.xpath('//div[@id="big-pic"]//a/img/@src') else tree.xpath('//div[@class="photo"]//p/img/@src')[0]
  61.     img_big_url_type = Img_big_url_type(img_big_url=img_big_url,img_type=tree.xpath('//div[@class="topmbx"]/a[last()]/text()')[0])
  62.     return img_big_url_type

  63. def mkdir(path) -> None:
  64.     """
  65.     创建文件夹
  66.     """
  67.     isExists = os.path.exists(path)
  68.     if not isExists:
  69.         os.makedirs(path)

  70. def quit() -> None:
  71.     """
  72.     退出
  73.     """
  74.     global sign
  75.     while True:
  76.         if keyboard.read_key()=='esc':
  77.             sign = False
  78.             console.print('[red]正在退出...')
  79.             break

  80. def retry(exceptions=Exception, tries=3):
  81.     """
  82.     重试装饰器
  83.     """
  84.     def decorator(func):
  85.         def wrapper(*args, **kwargs):
  86.             _tries = tries
  87.             while _tries > 0:
  88.                 try:
  89.                     return func(*args, **kwargs)
  90.                 except exceptions as e:
  91.                     _tries -= 1
  92.                     if _tries == 0:
  93.                         raise e
  94.                     time.sleep(1)
  95.         return wrapper
  96.     return decorator

  97. @retry()
  98. def start() ->Text:
  99.     """
  100.     开始
  101.     """
  102.     print('开始页码请不要输入0')
  103.     start_page = input('请输入开始页码:').strip()
  104.     if start_page == '0':
  105.         console.print('[red]请输入正确的页码!')
  106.         raise Exception('出错次数过多!')

  107.     print('结束页码请不要超过440')
  108.     end_page = input('请输入结束页码:').strip()
  109.     if int(end_page) > 440:
  110.         console.print('[red]请输入正确的页码!')
  111.         raise Exception('出错次数过多!')
  112.     return start_page,end_page
  113.      
  114. async def main() -> None:
  115.     """
  116.     主函数
  117.     """
  118.     Thread(target=quit).start()
  119.     start_page,end_page = start()
  120.     start_time = time.time()
  121.     for num in range(int(start_page),int(end_page)+1):
  122.         # 网站共计440页
  123.         url = f'https://www.mmonly.cc/gqbz/list_41_{num}.html'
  124.         resp_text = await get_html(url)
  125.         get_img_url_name_list = get_img_url_name(resp_text)
  126.         for img_url_name in get_img_url_name_list:
  127.             resp_text_big_img = await get_html(img_url_name.img_url)
  128.             # 图片标号开始为1
  129.             img_num = 1
  130.             # 图片页码开始为2
  131.             page_num = 1
  132.             while sign:
  133.                 try:
  134.                     if page_num >= 2:
  135.                         resp_text_big_img = await get_html(next_img_big_url)
  136.                     img_big_url_type = get_big_img(resp_text_big_img)
  137.                     img_path = os.path.join('壁纸',img_big_url_type.img_type,img_url_name.img_name)
  138.                     mkdir(img_path)
  139.                     await save_img(img_big_url_type.img_big_url, img_path,f'{img_url_name.img_name}_{img_num}.jpg')
  140.                     img_num += 1
  141.                     page_num += 1
  142.                     next_img_big_url = '.'.join(img_url_name.img_url.split(".")[0:-1]) + "_" + str(page_num) + ".html"
  143.                 except:
  144.                     img_num = 1
  145.                     break
  146.         if sign == False:
  147.             break
  148.     console.print(f'[red]全部下载完成! 耗时{time.time() - start_time:.2f}秒')


  149. if __name__ == '__main__':
  150.     loop = asyncio.get_event_loop()
  151.     loop.run_until_complete(main())
复制代码
以下为效果
QQ截图20220806142122.png
QQ截图20220806142137.png
异步.png
QQ截图20220806142035.png

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|偏爱技术社区-偏爱技术吧-源码-科学刀-我爱辅助-娱乐网--教开服-游戏源码

偏爱技术社区-偏爱技术吧-源码-科学刀-我爱辅助-娱乐网-游戏源码

Powered by Discuz! X3.5

GMT+8, 2025-9-12 20:22 , Processed in 0.079736 second(s), 38 queries .

快速回复 返回顶部 返回列表