urllib库的使用上

urllib库的常用参数

  • urllib.requeset.Request: 能够携带参数向服务器发起请求
  • urllib.request.urlopen: 向服务器发起请求并获取服务器响应
  • urllib.parse: 转换编码格式
模拟客户端向百度发起请求
import urllib.parse
import urllib.request

# 定义基础得网址
base_url = "https://www.baidu.com"
# 向服务发起请求并获得响应
req = urllib.request.urlopen(base_url)
# 转换编码格式读出index.html文件
res = req.read().decode('utf-8')
print(res)

如上,我们并不能获取完整的网页源代码,因为百度会是别为程序的发起的请求,故我们需要需要携带请求头,这也是最基本的反反盘设置,这时我们就需要用到urllib.requeset.Request这个模块,因为这个模块能够携带请求头发起请求,当然后续也会用第三方库的requests模块。

# 添加headers访问
import  urllib.request
base_url = 'https://www.baidu.com/'
# 定义headers
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36'
}

# 携带请求头发起请求
req = urllib.request.Request(base_url,headers=headers)
# 获取服务器响应结果
res = urllib.request.urlopen(req)
# 读取index.html文件
html = res.read().decode('utf-8')
print(html)

这样我们就能利用urllib.requeset.Request模块获取完整的网页源代码,接下来我们看下百度搜索网页的带参数的网址如下:
https://www.baidu.com/s?wd=XXX,wd后面的就是我们搜索的内容,那我们来看下面这一段代码

import  urllib.request
base_url = 'https://www.baidu.com/s?wd=美女'
res = urllib.request.urlopen(base_url)
print(res)
#程序运行报错,报错的提示如下
UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-11: ordinal not in range(128)

出现上面这个问题的原因在我们携带中文参数发起请求的时候,会出现编码格式的问题,出现类似于这样的情况我们可以利用urllib.parse模块去解决,如下:

import urllib.request
import urllib.parse

# 当我们发起请求的网址带有中文网址的时候会出现编码问题,如下:
base_url = 'https://www.baidu.com/s?wd=美女'
# 解决办法,先将中文字符编码,再发起请求
wd = {'wd': "美女"}
code = urllib.parse.urlencode(wd)
# 进行字符串的拼接,实现最终编码过的网址
url = 'https://www.baidu.com/s?' + code
# 设置请求头信息
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36'
}
# 携带请求头向服务器发起请求
req = urllib.request.Request(url,headers=headers)
# 获取服务器响应
res = urllib.request.urlopen(req)
# 解码index.html文件
html = res.read().decode('utf-8')
#  保存文件到本地
with open('text.html','w',encoding='utf-8') as obj:
    obj.write(html)

当使用urllib.parse.urlencode()去进行格式转换的时候是字典,urllib还可以使用urllib.parse.quote()去转换,quote接受的是字符串参数,这个有兴趣的可以自己去试试。接下来我们来看下一个例子:

#'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735041519%2F1618485629%5F84828260%5F22420%5FsProdImgNo%5F1%2Ejpg%2F200'   
#这是一张王者荣耀的图片地址,遇到这种情况的话我们该如何去解决呢,如下:
hero_url = 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735041519%2F1618485629%5F84828260%5F22420%5FsProdImgNo%5F1%2Ejpg%2F200' # 图片的url
# 很明显上面的网址不能够直接访问,那么我们可以通过unquote去将网址转换成网站能够正常访问的地址,再进行下一步操作。
img_url = urllib.parse.unquote(hero_url)
# 得到正常访问的网址
print(img_url)
百度贴吧小练习
#https://tieba.baidu.com/f?kw=%E5%9C%B0%E4%B8%8B%E5%9F%8E%E4%B8%8E%E5%8B%87%E5%A3%AB&ie=utf-8&pn=0
# https://tieba.baidu.com/f?kw=%E5%9C%B0%E4%B8%8B%E5%9F%8E%E4%B8%8E%E5%8B%87%E5%A3%AB&ie=utf-8&pn=50
# https://tieba.baidu.com/f?kw=%E5%9C%B0%E4%B8%8B%E5%9F%8E%E4%B8%8E%E5%8B%87%E5%A3%AB&ie=utf-8&pn=100
# 通过分析和观察发现根据贴吧的页数不同,pn后面的值也会随之发生变化,并且一也得变化值为50,这样我们就可以利用for循环进行翻页的爬取。
import  urllib.request
import   urllib.parse
#设置请求头
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36'
}
# 获取用户需求
user_key=input("请输入你要爬取的关键词:")
start=int(input("请输入开始的页数:"))
end=int(input("请输入结束的页数: "))
# 设置基础网址
base_url = "https://tieba.baidu.com/f?"
# 转换编码格式
base_kw = {"kw":user_key}
kw = urllib.parse.urlencode(base_kw)
for i in range(start,end+1):
	#对网址进行拼接
    url = base_url + kw + '=utf-8&pn=' + str((i -1)* 50)
    print(url)
    req = urllib.request.Request(url,headers=headers)
    res = urllib.request.urlopen(req)
    #读取数据
    html = res.read().decode('utf-8')
    filename =  str(i) + '.html'
    #保存数据
    with open(filename,'w',encoding='utf-8') as f:
        print("正在爬取第%s页" %  i )
        f.write(html)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值