• python学习之爬虫二


    1.requests模块中部分函数的介绍

     正则表达式的书写,同步处理,异步处理,带参数的处理

    import requests
    # 乌龙事件,没有来联网就去运行整个程序,肯定会报错啊
    # 没有联网,该台电脑怎么向目的主机发送请求呢
    # from urllib.parse import urlencode
    # # 在requests模块还为出现前使用的方法
    # url='https://www.baidu.com/s?'+urlencode({"wd":"牛超"})
    # headers = {
    #     'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36'}
    # print(url)
    # response=requests.get(url,headers=headers)
    # with open('新牛超.html','w',encoding='utf-8')as f:
    #     f.write(response.text)
    '''
    请求参数params
    访问百度搜查安徽工程大学url
    https://www.baidu.com/s?wd=安徽工程大学&pn=10  
    对应第二页
    https://www.baidu.com/s?wd=安徽工程大学&pn=20
    对应第三页
    由规律可知页数与pn的值有关
    '''
    url='https://www.baidu.com/s?'
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36'
    }
    response=requests.get(url,headers=headers,params={"wd":"安徽工程大学",'pn':'20'})
    # 此时爬取到网页上的文本文件,再以html的形式保存
    # 等价于用文本文档写网页,再用html形式保存
    with open('安徽工程大学.html','w',encoding='utf-8')as f:
        f.write(response.text)
    # 异步爬取
    # 线程池,限制开设多少个线程,开设的线程即是内存资源
    # 导入线程池模块
    import  requests
    import re
    import uuid
    # 导入线程池模块
    from concurrent.futures import ThreadPoolExecutor
    pool=ThreadPoolExecutor(50)
    # 比如开设50个线程同时执行任务
    def get_page(url):
        print(f'开始异步任务:{url}')
        response = requests.get(url)
        return response
    # 2. 解析数据
    # *?直接匹配
    # 异步请求,初次不显示,浏览器会再次执行JS代码,帮我们二次发送请求
    # 这个是时候可以查看网页源代码
    '''<video webkit-playsinline="" playsinline="" x-webkit-airplay="" autoplay="autoplay" src="https://video.pearvideo.com/mp4/adshort/20190613/cont-1565846-14013215_adpkg-ad_hd.mp4" style=" 100%; height: 100%;"></video>
    '''
    def parse_index(res):
        response=res.result()
        res = re.findall('<a href="video_(.*?)"', response.text, re.S)
        #  爬取出全部的id给res
        #  逐个取出id给m_id,然后与前面的url逐个进行拼接
        for m_id in res:
            detail_url = 'https://www.pearvideo.com/video_' + m_id
            pool.submit(get_page,detail_url).add_done_callback(parse_detail)
    # 解析详情页获取视频url
    def parse_detail(res):
        response=res.result()
        movie_url=re.findall('srcUrl="(.*?)"',response.text,re.S)[0]
        pool.submit(get_page, movie_url).add_done_callback(save_movie)
    # 保存数据
    def save_movie(res):
        movie_res=res.result()
        with open (f'{uuid.uuid4()}.mp4','wb')as f:
            f.write(movie_res.content)
            print(f'视频下载结束:{movie_res.url}')
            f.flush()  # 刷新
    
    # pool想当于一个开关
    if __name__ == '__main__':
        url='https://www.pearvideo.com/'
        # 将url给get_page()这个函数,这里写函数名即可
        # 异步提交,把视频传给get_page函数,把返回的结果传给save_movie函数
        # 往get_page发送异步请求,把结果交给parse_index函数
        pool.submit(get_page,url).add_done_callback(parse_index)
    '''
    关于request模块的讲解
    '''
    import requests
    import  re #正则模块
    import uuid # uuid.uuid4()可以根据时间戳生成一段世界唯一的数字
    # 对立视频详情页发送请求,获取响应数据
    # respone=requests.get(url='https://www.pearvideo.com/')
    # print(respone.status_code)
    # print(type(respone.status_code))
    # re.findall('正则匹配规则','解析文本','正则模式')
    # re.S全局模式(对整个文本进行匹配)
    # 加?非贪婪匹配
    #ctrl f 出现搜索框,在里面可以输入查找条件
    #获取主页视频详情页id
    # .指的是当前位置
    # *指的是插查找所有
    # 下面指的是提取ID
    # res=re.findall('<a href="video_(.*?)"',respone.text,re.S)
    # print(res)
    # for m_id in res:
    #     detail_url='https://www.pearvideo.com/video_'+m_id
    #     print(detail_url)
    
    # 爬虫三部曲:
    '''
    爬取数据的前提示要先针对一个分析,他们的url形式是什么样的,从而来书写
    正则表达式
    '''
    # 1.发送请求
    def get_page(url):
        response = requests.get(url)
        return response
    # 2. 解析数据
    # *?直接匹配
    # 异步请求,初次不显示,浏览器会再次执行JS代码,帮我们二次发送请求
    '''<video webkit-playsinline="" playsinline="" x-webkit-airplay="" autoplay="autoplay" src="https://video.pearvideo.com/mp4/adshort/20190613/cont-1565846-14013215_adpkg-ad_hd.mp4" style=" 100%; height: 100%;"></video>
    '''
    def parse_index(text):
        res = re.findall('<a href="video_(.*?)"', text, re.S)
        #  print(res)
        detail_url_list=[]
        for m_id in res:
            detail_url = 'https://www.pearvideo.com/video_' + m_id
            detail_url_list.append(detail_url)
        return detail_url_list
    # 解析详情页获取视频url
    def parse_detail(text):
        movie_url=re.findall('srcUrl="(.*?)"',text,re.S)[0]
        return  movie_url
    # 保存数据
    def save_movie(movie_url):
        response=requests.get(movie_url)
        with open (f'{uuid.uuid4()}.mp4','wb')as f:
            f.write(response.content)
            f.flush()# 刷新
    # 正式开始:
    if __name__ == '__main__':
    # if _name_=='__main__':# main+回车键
        #  1.对主页发送请求
        index_res = get_page(url='https://www.pearvideo.com/')
        #  2.对主页进行解析、获取详情页id
        detail_url_list=parse_index(index_res.text)
        # print(detail_url_list)
        #  3.对每个详情页url发送请求
        for detail_url  in detail_url_list:
            detail_res=get_page(url=detail_url)
            # print (detail_res.text)
            # 4.解析详情页获取视频URL
            movie_url=parse_detail(detail_res.text)
            print(movie_url)
    # 保存数据
            save_movie(movie_url)
    
  • 相关阅读:
    HDU
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3895】数字对【ST表】
    【JZOJ3895】数字对【ST表】
    【JZOJ3894】改造二叉树【树】【LIS】
    【JZOJ3894】改造二叉树【树】【LIS】
    【洛谷P4014】【网络流24题】分配问题【费用流】
  • 原文地址:https://www.cnblogs.com/lhhhha/p/11025600.html
Copyright © 2020-2023  润新知