【Python 爬虫】urllib库的简单操作

注:urllib是python自带的包,不需要安装,直接导入即可使用

一、get请求

# urllib网络请求是python自带的
import urllib
#请求
from urllib import request

if __name__ == '__main__':
    # 服务器响应
    response1 = urllib.request.urlopen(url="http://www.baidu.com")
    text = response1.read().decode("utf-8")
    with open('baidu.html', mode='w', encoding='utf-8') as fp:
        fp.write(text)
        print('文本数据已写入')

    picture='https://tse4-mm.cn.bing.net/th/id/OIP.F64SlQFR9lbjnlDYm4ojOAHaEo?pid=Api&rs=1'
    response = urllib.request.urlopen(url=picture)
    text = response.read()
    with open('picture.jpg', mode='wb') as fp:# 二进制是最原始的数据,无需进行编码
        fp.write(text)
        print('图片数据已写入')

结果:
在这里插入图片描述
在这里插入图片描述

上述代码为urllib的get请求操作,里面主要是urlopen函数,以及decode函数,打开百度一下的源代码,可以看到,百度网页是charset=utf-8,所以只需要解码即可,至于为什么需要解码,是因为汉字是不能被传送的,需要将汉字编码,故,当百度服务器响应的报文在保证传输的时候就已经被编码了,得到数据后,我们只需要进行解码即可。

如果不进行解码,得到的结果是这样子的:

<title>\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b\xef\xbc\x8c\xe4\xbd\xa0\xe5\xb0\xb1\xe7\x9f\xa5\xe9\x81\x93</title>

解码后:

<title>百度一下,你就知道</title>

综上可以看出,URL是统一资源定位符,任何一个URL都对应万维网上的资源,哪怕是图片或者视频资源,它们都有他们的内容,区别是我们用什么后缀的文件来接收他们,如爬取图片,那么返回的数据,是图片数据,只有用图片后缀,才能正确解析图片内容,但是从本质上,网页和图片、视频并无区别,网页是用html来接收而已,故,它们都是互联网上的数据流而已。

二、自定义请求头,携带Cookie实现模拟登录

import gzip
import urllib
from io import BytesIO
from urllib import request

'''携带Cookie实现模拟登录'''

if __name__ == '__main__':

    '''方法一'''
    '''
    构建headers的时候,复制浏览器F12 Network中的Request Headers 部分
    使用正则表达式将其变为字典格式:
        1.快捷键 Ctrl + r
            第一栏:(.*): (.*)
            第二栏:'$1':'$2',
            replace all
    '''
    # 定义Headers
    # 构建的时候,不需要
    # :authority :method :path :scheme 从accept开始即可
    headers = {'authority': ' weibo.com',
               'method': ' GET',
               'path': ' /u/7280903412/home?wvr=5',
               'scheme': ' https',
               'accept': ' text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
               'accept-encoding': ' gzip, deflate, br',
               'accept-language': ' zh-CN,zh;q=0.9',
               'cache-control': ' max-age=0',
               'cookie': "浏览器上的cookie",
               'referer': 'https: //weibo.com/u/7280903412/home?wvr=5',
               'sec-fetch-dest': ' document',
               'sec-fetch-mode': ' navigate',
               'sec-fetch-site': ' same-origin',
               'sec-fetch-user': ' ?1',
               'upgrade-insecure-requests': ' 1',
               'user-agent': ' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36', }
    # Request 请求
    # 构造 Request 请求对象
    url = 'https://weibo.com/u/7280903412/home?wvr=5'
    request1 = request.Request(url=url, headers=headers)
    # 发起请求
    response = urllib.request.urlopen(request1)
    # 打印网页中的数据
    htmls = response.read()
    # 由于网页的数据是以 b'\x 开头的,貌似全是16进制数据,即被gzip加密了的,需要进行解码
    buff = BytesIO(htmls)
    f = gzip.GzipFile(fileobj=buff)
    htmls = f.read().decode('utf-8')
    #print(htmls)

    '''方法二'''
    request2 = request.Request(url=url)
    request2.add_header('cookie', "浏览器上的cookie")
    # 发起请求
    response = urllib.request.urlopen(request2)
    # 打印网页中的数据
    # 这种方法是没有被加密的,不需要gzip解码
    # 这种结果与一般的结果没有太大区别,就是开头带一个b
    htmls = response.read().decode('utf-8')

    print(htmls)

上述代码实现了微博的模拟登录,cookie中携带了用户信息,使得跳过了登录界面,可以直接获得用户信息。如上所示,添加cookie有两种方式,一种是在模拟header里面添加,一种是在request里面直接添加。上述代码采用了urlopen函数来发送Request请求,而不是用urlopen来发送url信息。注意,header没必要全部写全,只需要写需要的部分即可,如只需要cookie,可以只写cookie。其次是cookie是有时效性的,过段时间就会失效。

这个cookie就是按F12,在浏览器的network上找到的cookie信息,发送到特定url需要携带特定的cookie。
在这里插入图片描述

三、带参数的get请求

import urllib
from urllib import request
from urllib import parse

# 测试get请求
url1 = 'http://httpbin.org/get?{}'
url2 = 'http://httpbin.org/get?%s'
if __name__ == '__main__':
    params = {'age':35,'sex':'男','work_years':'15'}
    # 因为params中有'男',所以需要编码
    params = parse.urlencode(params)
    response = urllib.request.urlopen(url=url1.format(params))
    response = urllib.request.urlopen(url=url2%params)
    print(response.read().decode('utf-8'))
    # 这里的带参数,指的是get中带参数,参数都是暴露在url后面,故使用urlopen的时候,url需要拼接
    # 不使用urlopen函数中自带的data参数,因为如果指定data的话,说明请求时post请求

结果:
在这里插入图片描述

上述代码中比较重要的就是一个网站,以及两种添加params的方式,以及使用urllib需要手动编码params

http://httpbin.org/

上面的网站,可以测试get、post请求,可以获取访问主机的ip地址

四、带参数的post请求

import urllib
from urllib import request
from urllib import parse

# 当进行post请求的时候,是不带/的,因为这是一种服务,不是一个目录,带有/说明是一个目录
# 所以当访问一个目录的时候,即含有子文件的时候,需要带上/,不是目录,本身是一种单独的服务的时候不能加上/
url = 'http://httpbin.org/post'

if __name__ == '__main__':
    '''
        对于encode()和decode():
            我们强调的编码指的是一种规则,比如将utf-8编码转换成byte编码,是按照byte编码规则进行编码,与具体内容无关,
            同样的,我们拿到一串编码可以看出是byte编码,这样,只需解码即可,我们无需关心以前是那种编码加密成的byte,
            按照规则对byte编码序列进行解码,解出来的是啥就是啥,从解出来的串类型,我们才能看出以前是那种编码
    '''
    params = {'Language':'Python','salary':20000,'work_time':996}
    # encode()将params 从str类型转换成byte类型
    params = parse.urlencode(params).encode()
    # 模拟post请求
    # 默认代码发起请求的时候,请求头"User-Agent": "Python-urllib/3.7"
    response = urllib.request.urlopen(url=url,data=params)
    print(response.read().decode())

结果:
在这里插入图片描述

上述代码为http://httpbin.org网址测试的post请求。注意urllib使用的post请求,需要将参数编码为byte类型

五、使用retrieve获取视频,自动存储到本地

import urllib
from urllib import request

# 下载视频到本地磁盘
url = 'http://vfx.mtime.cn/Video/2019/08/28/mp4/190828213254920717_480.mp4'

if __name__ == '__main__':
    # 高级方法,不需要打开文件,封装好的方法
    print('begin')
    urllib.request.urlretrieve(url = url, filename='video.mp4')
    print('ok')

上述代码的filename字段指定了视频需要被下载到哪里,urlretrieve方法是被封装好的,自动下载
在这里插入图片描述

六、IP代理

import urllib
from urllib import request

# 免费代理,快代理
# https://www.kuaidaili.com/free/inha/

if __name__ == '__main__':
    # 返回访问此接口的IP地址
    url = 'http://httpbin.org/ip'
    # 不使用代理发起请求
    response1 = urllib.request.urlopen(url = url)

    # print(response.getcode())# 获取响应状态码
    # print(response.geturl()) # 获取访问地址
    print(response1.read().decode())

    # 使用代理
    ph = urllib.request.ProxyHandler({'http':'61.163.32.88:3128'})
    # 打开者,打开url
    opener = urllib.request.build_opener(ph)
    # 使用代理打开一个网址
    response2 = opener.open(url)

    print('使用的代理IP是:',response2.read().decode())

这个是urllib使用代理IP访问其他网站的实例,由于代理IP不稳定,故不贴出结果,如果获取了很多的代理IP,可以使用random.choice(proxies)来从proxies中随机选择一个代理IP。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值