urllib使用
前言:
2、图片防盗链
原理:referer 上一级页面
1、urllib.parse
处理参数的
quote() https://www.baidu.com/s?ie=UTF-8&wd=%E4%B8%91%E5%A5%B3
url里面不能出现中文。
unquote() url解码函数
urlencode() 传递一个字典,将字典转化为键=值&键=值的格式,并且将里面的非法字符进行编码
3、模拟各种请求方式
get
需求:写代码,要求输入搜索关键字,然后将对应的内容保存到以关键字命名的html文件中
post
百度翻译
ajax-post
肯德基店铺
ajax-get
豆瓣电影
4、百度贴吧
https://tieba.baidu.com/f?kw=%E6%9D%8E%E6%AF%85&ie=utf-8&pn=100
kw:贴吧名字
ie:字符集
pn:第二页 50 第三页100 第一页 0 第四页 150
第n页:(n-1)*50
写一个程序,输入贴吧名字,输入要爬取的起始页码,结束页码,将所有页码的内容全部获取下来放到指定的文件中(文件放到以贴吧名字命名的文件夹中)
5、URLError\HTTPError
在这个模块中 urllib.error
URLError\HTTPError都是异常处理类,为了让代码更加的健壮
Exception : 官方的异常基类,所有的异常类都是直接或者间接的继承这个类
URLError :如果断网或者主机不存在
HTTPError : 请求的资源不存在,比如404
URLError可以捕获HTTPError,说明他是HTTPError的父类,如果多个except进行捕获,那么URLError要写到HTTPError的下面
6、Handler处理器、自定义Opener
在请求里面,还有两个高级功能,一个是代理,一个是cookie,上面学的内容都实现不了这两个高级功能。
学习handler和opener使用的步骤: 见代码
7、代理
生活中的代理:代驾,代孕,代练,代购
程序中:看图形
代理服务器平台:西刺代理,快代理,芝麻代理,阿布云代理
1、防盗链
import urllib.request
#没有防盗链机制的图片下载
'''
url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542687629144&di=31f17170a7414293f237ca299af5915e&imgtype=0&src=http%3A%2F%2Fimg.mp.sohu.com%2Fq_mini%2Cc_zoom%2Cw_640%2Fupload%2F20170801%2Fb4da8652ff5c418484109a4535def693_th.jpg'
#urllib.request.urlretrieve(url, 'luoli.jpg')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
#构建请求对象
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
with open('luoli1.jpg', 'wb') as fp:
fp.write(response.read())
'''
#有防盗链机制的图片下载
url = 'http://fm.shiyunjj.com/2018/1535/2ipw.jpg'
#urllib.request.urlretrieve(url, 'meinv.jpg')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
'Referer': 'http://www.mmjpg.com/',
}
#构建请求对象
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
with open('meinv2.jpg', 'wb') as fp:
fp.write(response.read())
2、quote-url编码
import urllib.parse
url = 'https://www.baidu.com/s?ie=UTF-8&wd=丑女'
# https%3A//www.baidu.com/s%3Fie%3DUTF-8%26wd%3D%E4%B8%91%E5%A5%B3
string = urllib.parse.quote(url)
# 【注】在你使用quote的时候,如果不需要将整个url进行编码,那你应该先将参数进行编码,然后再拼接到url的后面
# print(string)
# url解码函数
urlt = urllib.parse.unquote(string)
print(urlt)
3、urlencode-拼接请求函数
import urllib.parse
name = '狗蛋'
pwd = '123456'
height = 180
url = 'http://www.baidu.com/index.html?'
# get参数都写到一个字典中
data = {
'username': name,
'password': pwd,
'height': height
}
query_string = urllib.parse.urlencode(data)
print(query_string)
#如何实现url的拼接
'''
lt = []
for k, v in data.items():
lt.append(k + '=' + urllib.parse.quote(str(v)))
query_string = '&'.join(lt)
'''
#print(query_string)
#url += query_string
#print(url)
4、get-搜索关键字
import urllib.request
import urllib.parse
keyword = input('请输入要搜索的关键字-')
url = 'https://www.baidu.com/s?'
# 将参数写成一个字典
data = {
'ie': 'utf8',
'wd': keyword,
}
# 将字典转化为query_string 的格式
query_string = urllib.parse.urlencode(data)
# 拼接到url的后面
url += query_string
# 构建请求对象
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
#发送请求,得到响应
response = urllib.request.urlopen(request)
filename = keyword + '.html'
with open(filename, 'wb') as fp:
fp.write(response.read())
5、post-百度翻译简介
import urllib.request
import urllib.parse
word = 'baby'
url = 'https://fanyi.baidu.com/sug'
#表单数据
formdata = {
'kw': word
}
#构建请求对象
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
#向request发送post请求
#无论是get还是post,使用的方法都是urlopen()方法,不同的是,post有一个data参数。而get没有
#首先对formdata进行处理
formdata = urllib.parse.urlencode(formdata).encode('utf8')
response = urllib.request.urlopen(request, data=formdata)
print(response.read().decode('utf8'))
6、post-百度翻译详情
import urllib.request
import urllib.parse
word = 'baby'
url = 'https://fanyi.baidu.com/v2transapi'
formdata = {
'from': 'en',
'to': 'zh',
'query': word,
'transtype': 'realtime',
'simple_means_flag': '3',
# 加密措施,这两个参数必须写对才会给你结果。模拟js代码实现这两个参数,然后写到这里即可破解成功
'sign': '285360.47489',
'token': 'b49f7a8a9cd20fe8f00c318be394f28c',
}
formdata = urllib.parse.urlencode(formdata).encode('utf8')
headers = {
'Accept': '*/*',
# 'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
# 'Content-Length': '122',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': 'BIDUPSID=47F4D2484BDA10D2AA985C16068BB214; PSTM=1541084009; to_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; from_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BAIDUID=47F4D2484BDA10D2AA985C16068BB214:SL=0:NR=10:FG=1; delPer=0; H_PS_PSSID=26522_1430_21104_27400_26350_27244_27509; PSINO=2; locale=zh; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1541825894,1542681449; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1542681449',
'Host': 'fanyi.baidu.com',
'Origin': 'https://fanyi.baidu.com',
'Referer': 'https://fanyi.baidu.com/?aldtype=16047',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
# ajax请求
'X-Requested-With': 'XMLHttpRequest',
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request, data=formdata)
print(response.read().decode('utf8'))
百度翻译最新接口
7、ajax_post:肯德基餐厅查询
import urllib.request
import urllib.parse
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
cname = input('请输入要查询的城市名称-')
formdata = {
'cname': cname,
'pid': '',
'pageIndex': '1',
'pageSize': '10',
}
formdata = urllib.parse.urlencode(formdata).encode('utf8')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request, data=formdata)
print(response.read().decode('utf8'))
8、ajax_get
import urllib.request
import urllib.parse
'''
21-40 第二页
start=20
limit=20
1-20 第一页
start=0
limit=20
第三页
start=40
limit=20
第n页的20个数据
start=(n-1)*20
limit=20
'''
print('每页共有10条数据')
number = 10
page = int(input('请输入你要的第几页的数据-页码:'))
url = 'https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&'
#根据页码和每页显示的个数计算start和limit
start = (page-1) * number
limit = number
#get参数
data = {
'start': start,
'limit': limit
}
query_string = urllib.parse.urlencode(data)
url += query_string
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf8'))
9、贴吧
import urllib.request
import urllib.parse
import os
import time
# 输入贴吧的名字
baname = input('请输入要爬取的贴吧名字-')
# 输入起始页码和结束页码
start_page = int(input('请输入起始页码-'))
end_page = int(input('请输入结束页码-'))
url = 'https://tieba.baidu.com/f?'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
}
# 搞一个循环,循环的来爬取每一页数据
for page in range(start_page, end_page + 1):
print('开始下载第%s页......' % page)
# 计算出来pn
pn = (page-1) * 50
# 拼接对应页码的url
data = {
'kw': baname,
'ie': 'utf8',
'pn': pn
}
query_string = urllib.parse.urlencode(data)
url_t = url + query_string
# print(url_t)
# 构建请求对象
request = urllib.request.Request(url=url_t, headers=headers)
# 发送请求,得到响应
response = urllib.request.urlopen(request)
# 读取字符串内容
content = response.read().decode('utf8')
# 文件名字 李毅_第1页.html
filename = '%s_第%s页.html' % (baname, page)
# 通过代码创建吧名命名的文件夹
dirname = baname
# 判断文件夹是否存在
if not os.path.exists(dirname):
os.mkdir(dirname)
# 拼接文件的全路径
filepath = os.path.join(dirname, filename)
# 保存到指定的文件中
with open(filepath, 'w', encoding='utf8') as fp:
fp.write(content)
print('结束下载第%s页' % page)
time.sleep(5)
10、error
import urllib.request
import urllib.error
# mi.com xiaomi.com jd.com 360buy.com sb.com
# url = 'http://www.maodan.com/'
url = 'https://www.cnblogs.com/fh-fendou/p/7479811.html'
try:
response = urllib.request.urlopen(url)
except urllib.error.HTTPError as e:
print(e)
except urllib.error.URLError as e:
print(e)
print('恭喜你赢了')
11、handler
import urllib.request
url = 'http://www.baidu.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
}
request = urllib.request.Request(url=url, headers=headers)
#第一步, 创建一个handler
handler = urllib.request.HTTPHandler()
#第二步,根据handler创建一个opener
opener = urllib.request.build_opener(handler)
#再往下发送请求的时候使用opener.open()发送即可,不要用urlopen发送
response = opener.open(request)
print(response.read().decode('utf8'))