• python中urllib库的使用


    1. 获取目标页面的源码

    以获取百度页面源码为例

    #使用urllib获取百度首页的源码
    import urllib.request
    
    #1 定义一个url 作为需要访问的网址
    url = 'http://www.baidu.com'
    
    #2 模拟浏览器向服务器发送请求 response响应
    response = urllib.request.urlopen(url)
    
    #3 获取响应中的页面源码
    content = response.read()
    print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    直接这样输出的结果会是一堆二进制文件,这是因为read返回的是字节形式的二进制数据,因此需要转换成字符串,也就是解码,具体方式是decode('编码的格式')
    而编码的格式则需要在输出里找charset
    在这里插入图片描述
    content = response.read().decode('utf-8')解码之后再输出,就可以看到输出结果里会出现汉字了

    #使用urllib获取百度首页的源码
    import urllib.request
    
    #1 定义一个url 作为需要访问的网址
    url = 'http://www.baidu.com'
    
    #2 模拟浏览器向服务器发送请求 response响应
    response = urllib.request.urlopen(url)
    
    #3 获取响应中的页面源码
    #read 返回的是字节形式的二进制数据 因此需要转换成字符串 也就是解码 decode('编码的格式')
    #content = response.read() 在输出内容里看charset是utf-8
    content = response.read().decode('utf-8')
    print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    2. 一个类型和六个方法

    一个类型指的是responseHTTPResponse的类型
    六个方法是read() readline() readlines() getcode() geturl() getheaders()

    import urllib.request
    
    url = 'http://www.baidu.com'
    
    #模拟浏览器向服务器发送请求
    response = urllib.request.urlopen(url)
    
    #一个类型和六个方法
    # response 是HTTPResponse的类型
    print(type(response))
    
    #按字节去读 返回多少个字节
    content1 = response.read(5)
    print(content1)
    
    #按行读 只能读取一行
    content2 = response.readline()
    print(content2)
    
    #按行读 能读所有
    content3 = response.readlines()
    print(content3)
    
    #返回状态码,如果是200 就没错
    content4 = response.getcode()
    print(content4)
    
    #返回url地址
    content5 = response.geturl()
    print(content5)
    
    #获取状态信息
    content6 = response.getheaders()
    print(content6)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3. 进行下载

    3.1 下载网页

    import urllib.request
    
    #下载网页
    url_page = 'http://www.baidu.com'
    
    #url表示下载路径 filename表示文件名字
    #在python中,可以写变量名称,也可以直接写值
    urllib.request.urlretrieve(url_page,'baidu.html')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    执行这段逻辑后,就会在当前文件夹内多出来下载后的baidu.html文件,双击后就可以打开百度的网页
    在这里插入图片描述

    3.2 下载图片

    在百度上随便找一张图片,右键复制图片地址https://img0.baidu.com/it/u=3159466223,684024309&fm=253&fmt=auto&app=138&f=JPEG?w=480&h=360

    import urllib.request
    
    #下载网页
    url_page = 'http://www.baidu.com'
    
    #url表示下载路径 filename表示文件名字
    #在python中,可以写变量名称,也可以直接写值
    #urllib.request.urlretrieve(url_page,'baidu.html')
    
    #下载图片
    url_img = 'https://img0.baidu.com/it/u=3159466223,684024309&fm=253&fmt=auto&app=138&f=JPEG?w=480&h=360'
    
    urllib.request.urlretrieve(url = url_img,filename='guanyu.jpg')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    执行之后,就会发现下载到了当前文件夹下,并且可以直接双击打开
    在这里插入图片描述

    3.3 下载视频

    个人感觉找视频的地址会麻烦一点,随便找一个视频,在控制台里找video模块下的src,后面跟的地址就是视频地址,这里似乎有个小技巧,当你把鼠标移到正在播放的视频界面上时,系统会自动帮你高亮对应的前端代码,我这里随便找了一段https://vd4.bdstatic.com/mda-mftcyx0fwijsjqnj/sc/cae_h264/1624872013701360043/mda-mftcyx0fwijsjqnj.mp4?v_from_s=hkapp-haokan-hbe&auth_key=1662781316-0-0-0d102305b79f30b54f41e4213db3c308&bcevod_channel=searchbox_feed&pd=1&cd=0&pt=3&logid=0716485752&vid=6407922981306901952&abtest=104165_2-104378_2&klogid=0716485752
    在这里插入图片描述

    import urllib.request
    
    #下载网页
    url_page = 'http://www.baidu.com'
    
    #url表示下载路径 filename表示文件名字
    #在python中,可以写变量名称,也可以直接写值
    #urllib.request.urlretrieve(url_page,'baidu.html')
    
    #下载图片
    url_img = 'https://img0.baidu.com/it/u=3159466223,684024309&fm=253&fmt=auto&app=138&f=JPEG?w=480&h=360'
    
    #urllib.request.urlretrieve(url = url_img,filename='guanyu.jpg')
    
    #下载视频
    url_video = 'https://vd4.bdstatic.com/mda-mftcyx0fwijsjqnj/sc/cae_h264/1624872013701360043/mda-mftcyx0fwijsjqnj.mp4?v_from_s=hkapp-haokan-hbe&auth_key=1662781316-0-0-0d102305b79f30b54f41e4213db3c308&bcevod_channel=searchbox_feed&pd=1&cd=0&pt=3&logid=0716485752&vid=6407922981306901952&abtest=104165_2-104378_2&klogid=0716485752'
    
    urllib.request.urlretrieve(url_video,'video.mp4')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这段执行之后就会发现文件夹下多了一个视频文件,可以双击打开,只不过下载速度不太快
    在这里插入图片描述

    4. 定制请求对象

    直接爬取https协议的网址,会遭遇反爬

    import urllib.request
    
    url = 'https://www.baidu.com'
    
    # url的组成
    # http https www.baidu.com 80/443
    # 协议     主机     端口号     路径     参数     锚点
    # http    80
    # https    443
    
    response = urllib.request.urlopen(url)
    content = response.read().decode('utf-8')
    print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出的结果很少
    在这里插入图片描述
    这时候就需要在逻辑里进行伪装,将代码模拟成浏览器进行网页访问,可以在浏览器内查看自己电脑的user-agent
    在这里插入图片描述
    user-agent放进代码里

    import urllib.request
    
    url = 'https://www.baidu.com'
    
    # url的组成
    # http https www.baidu.com 80/443
    # 协议     主机     端口号     路径     参数     锚点
    # http    80
    # https    443
    
    headers = {
        'User-Agent' : '此处填写自己的user-agent'
    }
    
    request = urllib.request.Request(url=url,headers=headers)
    
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    就可以正常访问了

    5. 编解码

    5.1 get请求

    5.1.1 get请求中的quote方法

    如果直接执行这段逻辑会报错

    #https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
    import urllib.request
    url = 'https://www.baidu.com/s?wd=周杰伦'
    
    headers = {
        'User-Agent' : '此处填写自己的user-agent'
    }
    # 定制请求对象
    request = urllib.request.Request(url=url,headers=headers)
    
    #模拟浏览器向服务器发送请求
    response = urllib.request.urlopen(request)
    
    # 获取响应的内容
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    这是因为默认使用ASCII编码,而在这种编码里,不支持汉字,如果将逻辑中的url = 'https://www.baidu.com/s?wd=周杰伦'变成https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6,就可以正常输出结果,相当于是把周杰伦三个汉字改成Unicode编码,当然这种事情应该让脚本自己完成,只需要加上name = urllib.parse.quote('周杰伦')

    #https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
    import urllib.request
    import urllib.parse
    url = 'https://www.baidu.com/s?wd='
    
    headers = {
        'User-Agent' : '此处填写自己的user-agent'
    }
    
    #将汉字转变为Unicode 需要依赖parse库
    name = urllib.parse.quote('周杰伦')
    
    #更新url变量
    url = url + name
    
    # 定制请求对象
    request = urllib.request.Request(url=url,headers=headers)
    
    #模拟浏览器向服务器发送请求
    response = urllib.request.urlopen(request)
    
    # 获取响应的内容
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    运行上面这段逻辑,就可以正常访问了

    5.1.2 get请求中的urlencode方法

    当需要修改的值过多时,quote方法会很麻烦,这时候可以考虑使用urlencode

    import urllib.parse
    
    data = {
        'wd':'周杰伦',
        'sex':'男'
    }
    
    a = urllib.parse.urlencode(data)
    print(a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    就会直接输出转码之后的结果
    在这里插入图片描述

    5.2 post请求

    5.2.1 百度翻译

    get请求方式的参数必须编码,参数是拼接到url后面,编码之后不需要调用encode方法
    post请求方式的参数必须编码,参数是放在请求对象定制的方法中,编码之后需要调用encode方法

    #post请求
    import urllib.request
    import urllib.parse
    
    url = 'https://fanyi.baidu.com/sug'
    
    headers = {
        'User-Agent' : '此处填写自己的user-agent'
    }
    
    keyword = input('请输入您要查询的单词:')
    
    data = {
        'kw' : keyword
    }
    
    #post请求的参数 需要进行编码
    data = urllib.parse.urlencode(data).encode('utf-8')
    
    #post的参数 不会拼接在url后  需要放在请求对象定制的参数中
    request = urllib.request.Request(url=url,data=data,headers=headers)
    
    #模拟浏览器发送请求
    response = urllib.request.urlopen(request)
    
    # 获取响应的数据
    content = response.read().decode('utf-8')
    
    #字符串 》json对象
    import json
    obj = json.loads(content)
    
    print(obj)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    运行这段逻辑会要求输入需要翻译的单词,如果输入spider,就会得到返回结果
    在这里插入图片描述

    5.2.2 百度详细翻译

    #post请求
    import urllib.request
    import urllib.parse
    
    url = 'https://fanyi.baidu.com/sug'
    
    headers = {'此处填写自己的header'}
    
    data = {
        'from':'en',
        'to':'zh',
        'query':'love',
        'transtype':'realtime',
        'simple_means_flag':'3',
        'sign':'198772.518981',
        'token':'填写自己的token',
        'domain':'common'
    }
    
    #post请求的参数 需要进行编码
    data = urllib.parse.urlencode(data).encode('utf-8')
    
    #post的参数 不会拼接在url后  需要放在请求对象定制的参数中
    request = urllib.request.Request(url=url,data=data,headers=headers)
    
    #模拟浏览器发送请求
    response = urllib.request.urlopen(request)
    
    # 获取响应的数据
    content = response.read().decode('utf-8')
    
    #字符串 》json对象
    import json
    obj = json.loads(content)
    
    print(obj)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    6. ajax的get请求

    6.1 ajax的get请求豆瓣电影第一页

    #get请求 获取豆瓣电影的第一页数据 并保存
    
    import urllib.request
    import urllib.parse
    url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&start=0&limit=20'
    
    headers = {'此处填写自己的header'}
    
    # 定制请求对象
    request = urllib.request.Request(url=url,headers=headers)
    
    #模拟浏览器向服务器发送请求
    response = urllib.request.urlopen(request)
    
    # 获取响应的内容
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    #print(content)
    
    # 数据下载到本地
    # 默认使用gbk 保存中文就需要改成utf-8
    # fp = open('douban.json','w',encoding='utf-8')
    # fp.write(content)
    
    with open('douban.json','w',encoding='utf-8') as fp:
        fp.write(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    执行这段逻辑后就会得到douban.json文件,打开后会是一长行的文件,此时可以通过快捷方式ctrl + alt + l将其分行展示,就可以得到豆瓣电影的第一页
    在这里插入图片描述

    6.2 ajax的get请求豆瓣电影前十页

    #get请求 获取豆瓣电影的第十页数据 并保存
    
    import urllib.request
    import urllib.parse
    
    def create_requests(page):
        base_url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&'
    
    #get请求格式
        data = {'start':(page - 1) * 20,
                'limit': 20}
    
        data = urllib.parse.urlencode(data)
    
        url = base_url + data
    
        headers = {
            '此处填写自己的header'}
    
        # 定制请求对象
        request = urllib.request.Request(url=url, headers=headers)
        return request
    
    def get_content(request):
        # 模拟浏览器向服务器发送请求
        response = urllib.request.urlopen(request)
        content = response.read().decode('utf-8')
        return(content)
        
    def down_load(page,content):
        with open('douban_' + str(page) +'.json', 'w', encoding='utf-8') as fp:
            fp.write(content)
    
    #程序入口
    if __name__ == '__main__':
        start_page = int(input('请输入起始的页码'))
        end_page = int(input('请输入结束的页码'))
    
        for page in range(start_page,end_page + 1):
            request = create_requests(page)
            #获取响应的数据
            content = get_content(request)
            #下载
            down_load(page,content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    执行完成后,会生成多个文件,打开之后就是豆瓣电影前十页的数据
    在这里插入图片描述

    6.3 ajax的post请求肯德基门店前十页

    #post 请求 访问肯德基前10页
    #查询网址 http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
    
    # cname: 北京
    # pid:
    # pageIndex: 2
    # pageSize: 10
    
    import urllib.request
    import urllib.parse
    
    def create_requests(page):
        base_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
    
        data = {'cname': '北京',
                'pid':'',
                'pageIndex': page,
                'pageSize': '10'}
    
        data = urllib.parse.urlencode(data).encode('utf-8')
    
        headers = {'此处填写自己的header'}
    
        # 定制请求对象
        request = urllib.request.Request(url=base_url, headers=headers, data=data)
        return request
    
    def get_content(request):
        # 模拟浏览器向服务器发送请求
        response = urllib.request.urlopen(request)
        content = response.read().decode('utf-8')
        return(content)
    
    def down_load(page,content):
        with open('kfc' + str(page) +'.json', 'w', encoding='utf-8') as fp:
            fp.write(content)
    
    #程序入口
    if __name__ == '__main__':
        start_page = int(input('请输入起始的页码'))
        end_page = int(input('请输入结束的页码'))
    
        for page in range(start_page,end_page + 1):
            request = create_requests(page)
            #获取响应的数据
            content = get_content(request)
            #下载
            down_load(page,content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    执行上面这段逻辑后,就会得到10个json文件
    在这里插入图片描述

  • 相关阅读:
    MS Access 教程之 ODBC 和本地表之间的链接缓慢?然后不要这样做。
    2022/10/29 SVN的安装与使用
    mybatis plus MetaObjectHandler 不生效
    计算机组成与结构
    pgz-sbv-gf极狐低代码平台发布
    【oj刷题记】【考研写法注意点】【1294】【多项式加法】【利用归并思想】【考研写法关于另外一个可能导致指针越界的问题】【以及遍历链表最保险的写法】
    利用异常实现短期hook
    特斯拉允许行车过程中玩游戏,车主:谢谢“好意”,已投诉
    C/C++输出第二个整数 2019年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
    狂神说Go语言学习笔记(三)
  • 原文地址:https://blog.csdn.net/weixin_44999258/article/details/126780913