爬虫学习-异步爬虫

  • 目的:在爬虫中使用异步实现高性能的数据爬取操作

  • 方式

  • 多线程、多进程(不建议)

  • 好处:可以为相关阻塞的操作单独开启进程或者线程,阻塞操作就可以异步执行

  • 弊端:无法无限制的开启多线程或者多进程

  • 线程池、进程池(适当使用)

  • 好处:我们可以降低系统对进程或者线程创建和销毁的一个频率,从而更好地降低系统的开销

  • 弊端:池中线程或者进程的数量是有上限

  • 实例:下载视频

# 爬取视频的视频数据
import requests
from lxml import etree
import re
from multiprocessing.dummy import Pool

# 原则:线程池处理的是阻塞且耗时的操作
# 对下述url发起请求解析出视频详情页的url和视频的名称
if __name__ == '__main__':
    # 人物页url
    homr_url = 'https://www.pearvideo.com/category_1'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54'
    }
    # 获取该页的响应数据
    page_text = requests.get(url=homr_url, headers=headers).text
    # 实例化etree对象
    tree = etree.HTML(page_text)
    # 获取该页中跳转到视频页的地址
    mp4_text = tree.xpath('//*[@id="listvideoListUl"]/li/div/a/@href')
    # 同时获取对应的名称
    mp4_title = tree.xpath('//*[@id="listvideoListUl"]/li/div/a/div[2]/text()')
    # 建立空列表,后面用来芳名称和链接
    urls = []
    i = 0
    for src in mp4_text:
        # 拼接跳转到视频页的链接
        page_src = 'https://www.pearvideo.com/' + src
        # 从中取出contId
        contld = page_src.split('_')[-1]
        # page_src是referer,contld是contId,必须要有这俩才能获取到相应的视频假链接
        # print(contld)
        headers = {
            'referer': page_src,
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54'
        }
        params = {
            'contId': contld
        }
        # 获取视频假链接
        mp4_url = 'https://www.pearvideo.com/videoStatus.jsp'
        mp4 = requests.get(url=mp4_url, headers=headers, params=params).text
        # 利用正则来找更
        ex = '"srcUrl":"(.*?)"'
        securl = re.findall(ex, mp4)[0]
        # 对链接进行分割和拼接,得到真的视频链接
        url = securl.split('-')
        new_url = 'https://video.pearvideo.com/mp4/short/20180313/cont-' + str(contld) + '-' + url[-2] + '-' + url[-1]
        # 将名称和链接以字典形式保存,并放进列表里
        dic = {
            'name': mp4_title[i],
            'url': new_url
        }
        urls.append(dic)
        i += 1
    print(urls)


# 下载视频的封装函数
def get_video_data(dic):
    url = dic['url']
    print(dic['name'] + '正在下载...')
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54'
    }
    mp4_data = requests.get(url=url, headers=headers).content
    filename = '梨视频/' + dic['name'] + '.mp4'
    # 持久化保存
    with open(filename, 'wb') as fp:
        fp.write(mp4_data)
    print(dic['name'] + '下载成功')


# 创建进程池
pool = Pool(4)
pool.map(get_video_data, urls)
pool.close()
pool.join()
  • 单线程+异步协程(推荐)

  • event_loop: 事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上当满足某些条件的时候,函数就会被循环执行。

  • coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。async 关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回我们可以使用个协程对象

  • task: 任务,它是对协程对象的进一步封装,包含了任务的各个状态

  • future: 代表将来执行或还没有执行的任务,实际上和 task 没有本质区别

  • async 定义一个协程

  • await 用来挂起阻塞方法的执行

  • requests.get是基于同步,必须使用基于异步的网络请求模块进行指定url的请求发送,若是用get还是6s,换成异步会变成2s

  • aiohttp:基于异步网络请求的模块

  • pip install aiohttp

  • 使用方法:变为2s

  • 协程

  • 协程不是计算机提供,是程序员人为创造

  • 协程也可以被称为微线程,是一种用户态内的上下文切换技术,简而言之,就是通过一个线程实现代码块相互切换执行

  • 协程意义

  • 在一个线程中如果遇到IO等待时间,线程不会傻傻等待,会利用空闲的时候干点其他事

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
描述:由C#编写的多线程异步抓取网页的网络爬虫控制台程序 功能:目前只能提取网络链接,所用的两个记录文件并不需要很大。网页文本、图片、视频和html代码暂时不能抓取,请见谅。 但需要注意,网页的数目是非常庞大的,如下代码理论上大概可以把整个互联网网页链接都抓下来。 但事实上,由于处理器功能和网络条件(主要是网速)限制,一般的家用电脑最多能胜任12个线程左右的抓取任务,抓取速度有限。可以抓取,但需要时间和耐心。 当然,这个程序把所有链接抓下来是可能的,因为链接占系统空间并不多,而且有记录文件的帮助,已抓取网页的数量可以堆积下去, 甚至可以把所有的互联网网络链接都存取下来,当然,最好是分批次。建议设置maxNum为500-1000左右,慢慢累积下去。 另外因为是控制台程序,有时候显示字符过多会系统会暂停显示,这时候只要点击控制台按下回车键就可以了。程序假死的时候,可以按回车键(Enter)试试。 /// 使用本程序,请确保已创建相应的记录文件,出于简化代码的考虑,本程序做的并不健壮,请见谅。 /// 默认的文件创建在E盘根目录“已抓取网址.txt”和“待抓取网址.txt”这两个文本文件中,使用者需要自行创建这两个文件,注意后缀名不要搞错。 这两个文件里面的链接基本都是有效链接,可以单独处理使用。 本爬虫程序的速度如下: 10线程最快大概500个链接每分钟 6-8线程最快大概400-500个链接每分钟 2-4线程最快大概200-400个链接每分钟 单线程最快大概70-100个链接每分钟 之所以用多线程异步抓取完全是出于效率考虑,本程序多线程同步并不能带来速度的提升,只要抓取的网页不要太多重复和冗余就可以,异步并不意味着错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Knoka705

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值