Python爬虫Urllib相关介绍及使用
一、相关概念及介绍
-
爬虫分类
- 通用爬虫
实例: 百度、360、google、sougou等搜索引擎---伯乐在线 功能: 访问网页->抓取数据->数据存储->数据处理->提供检索服务robots协议 一个约定俗成的协议,添加robots.txt文件,来说明本网站哪些内容不可以被抓取,起不到限制作用自己写的爬虫无需遵守 网站排名(SEO) 1、根据pagerank算法值进行排名 (参考个网站流量、点击率等指标) 2、百度竟价排名 缺点 1,抓取的数据大多是无用的 2.不能根据用户的需求来精准获取数据
- 聚焦爬虫
功能 根据需求,实现爬虫程序,抓取需要的数据 设计思路 1.确定要爬取的url 如何获取url 2.模拟浏览器通过http协议访问url,获取服务器返回的html代码 如何访问 3.解析html字符串 (根据一定规则提取需要的数据) 如何解析
-
反爬手段
1.User-Agent: User Agent中文名为用户代理,简称 UA,官是个特殊字符串头,CPU 类型、浏览器及版本、浏览器流染引警、浏览器语言、浏览器插件等。 2.代理IP 快代理 什么是高匿名、匿名和透明代理? 它们有什么区别? 1.使用透明代理,对方服务器可以知道你使用了代理,并且也知道你的真实IP。 2.使用匿名代理,对方服务器可以知道你使用了代理,但不知道你的真实IP。 3.使用高匿名代理,对方服务器不知道你使用了代理,更不知道你的真实IP 3.验证码访问 打码平台 云打码平台 4.动态加载网页 网站返回的是is数 并不是网页的真实数据 selenium驱动真实的浏览器发送请求 5.数据加室 分析js代码
二、urllib 基本使用
urllib.request.urlopen() 模拟浏览器向服务器发送请求
response 服务器返回的数据
response的数据类型是HttpResponse
字节-->字符串
解码decode
字符串-->字节
编码encode
read()
字节形式读取二进制扩展: rede(5)返回前几个字节
读取一行readline()
一行一行读取 直至结束readlines()
获取状态码
getcode()
getur1()获取ur1
getheaders()获取headers
urllib.request.urlretrieve()
请求网页
请求图片
请求视频
# 使用urllib获取网站源码
import urllib.request # 引入urllib
# 1 定义一个url
url = "http://www.baidu.com"
# 2 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(url)
# 3 获取响应中的页面的源码
# content = response.read()
# read方法,返回的是字节形式的二进制数据
# 二进制转为字符串 解码 decode('编码的格式')
content = response.read().decode("utf-8")
# 4 打印数据
print(content)
三、urllib 1个类型和6个方法
- 类型:HTTPResponse
- 方法:
- read(x):字节读取,x默认不填读取全部,填写代表读取字节数量
- readline():读取第一行
- readlines():读取所有行
- getcode():返回状态码,200代表成功
- geturl():返回访问的url地址
- getheaders():返回状态信息和请求头
import urllib.request # 引入urllib
# 1 定义一个url
url = "http://www.baidu.com"
# 2 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(url)
# 3 一个类型
# <class 'http.client.HTTPResponse'>
print(type(response))
# 4 6个方法
# read() 按照一个字节一个字节的读
content = response.read()
print(content)
# read(16) 返回16个字节
content = response.read(16)
print(content)
# readline() 读取第一行
content = response.readline()
print(content)
# readlines() 读取所有行
content = response.readlines()
print(content)
# 返回状态码 200代表成功
print(response.getcode())
# 返回访问的url地址
print(response.geturl())
# 返回访问的url地址
print(response.getheaders())
四、下载
- 网页
- 图片
- 视频
# 引入urllib
import urllib.request
# 1 下载网页
url = "http://www.baidu.com"
# url代表的是下载的路径 filename文件的名字
urllib.request.urlretrieve(url, "baidu.html")
# 下载图片
url_img = "https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF"
urllib.request.urlretrieve(url=url_img, filename="fengjin.gif")
# 下载视频
url_video = "https://vd7.bdstatic.com/mda-mfuf163rfmkn36i7/sc/cae_h264_nowatermark/1624963807340099361/mda-mfuf163rfmkn36i7.mp4?v_from_s=hkapp-haokan-hna&auth_key=1682579593-0-0-39ba3299c576397b8229b9b2f61c74d8&bcevod_channel=searchbox_feed&pd=1&cd=0&pt=3&logid=2593824574&vid=10554454971571011271&abtest=109133_1-109159_1&klogid=2593824574&sdk_xcdn=1"
urllib.request.urlretrieve(url=url_video, filename="shiping.mp4")
五、请求对象的定制
- UA:User-Agent
# 引入urllib
import urllib.request
# 1 网址
url = "https://www.baidu.com"
"""
默认端口
http 80
https 443
mysql 3306
oracle 1521
redis 6379
mongodb 27017
"""
response = urllib.request.urlopen(url)
content = response.read().decode("utf-8")
# 返回数据不完全
print(content)
# 请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
# urlopen方法中不能存储字典
# 请求对象的定制
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode("utf-8")
# 返回全部数据
print(content)
六、Get请求的
1 quote方法
- urllib.parse.quote()
# 引入urllib
import urllib.request
import urllib.parse
# https://www.baidu.com/s?wd=白梦妍
# 找到网页的源码
url = "https://www.baidu.com/s?wd="
# 对中文进行unicode编码
name = urllib.parse.quote("白梦妍")
url = url + name
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
print(content)
# 多参数
# 定义参数集合
data = {
'wd':'白梦妍',
'sex':'女'
}
# 对中文进行unicode编码
data_unicode = urllib.parse.quote(data)
print(data_unicode)
2 urlencode方法
- urllib.parse.urlencode()
# 引入urllib
import urllib.request
import urllib.parse
# https://www.baidu.com/s?wd=白梦妍&sex=女
# 找到网页的源码
url = "https://www.baidu.com/s?"
# 定义参数集合
data = {
'wd':'白梦妍',
'sex':'女'
}
# 对中文进行unicode编码
data_unicode = urllib.parse.urlencode(data)
print(data_unicode)
url = url + data_unicode
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
print(content)
七、Post请求
post请求的参数必须进行编码
urllib.parse.urlencode(data).encode(‘utf-8’)
1 单参数
# 引入urllib
import urllib.request
import urllib.parse
import json
url = "https://fanyi.baidu.com/sug"
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
# 定义参数集合
data = {"kw": "你好"}
# post请求的参数必须进行编码
data_unicode = urllib.parse.urlencode(data).encode('utf-8')
print(data_unicode)
request = urllib.request.Request(url=url, data=data_unicode, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
print(content)
print(type(content))
# str 转 json
obj = json.loads(content)
print(obj)
2 多参数
Accept-Encoding 一定要注释掉
# 引入urllib
import urllib.request
import urllib.parse
import json
url = "https://fanyi.baidu.com/v2transapi?from=en&to=zh"
# 请求对象定制[是为了解决反扒的第一种手段]
# Accept-Encoding 一定要注释掉
# Cookie 是必须的,其他都可以考虑不要
headers = {
# "Accept": "*/*",
## 'Accept-Encoding': 'gzip, deflate, br',
# "Accept-Language": "zh-CN,zh;q=0.9",
# "Acs-Token": "1682585241659_1682585388438_V/VDJiuYRbp0/4W9l+eyhej+adJrqetpRvlbKIjHPG92iMPLtP0Uw6K7Elpx9x8lxvl2Z29DW6LDg0CLWUGdZelexWzGYxoVZlViU62Xwdccmy1T9WsN+whiZ70QtnzzCoWiCBSbkkGMt3MXj7+77/NA2z3Abe8o1a7VAR9X6j2kFNjFXnN1gpsyHvhFAHM2EyCG/knbOWe4/o9oz5jG3zdQz3L1aUNwKCVFgytTHTb4b1gvEfOV35+nfV+GWHhW7I3kNkD9aF6soX30+7wzxpUl87WIK8iwSdbeF7jtAaOV4m80ps/RYsu7HiwGiEQPyj9YLGnoLa/LJtKPLbytJzIqo8kLpK5rD/YR8ZjBNhw0mW/Kkj6TUAvW27RioGRDm/p7wSBBors9My9j74ZBlobrLVu6dZ3rvYBUgZPftK7xE7uMGrjDEku8xLOuul11clBwVu0g6EW8WPOZFDfIAtNMu0LKcRkZc5MsFXHD6tuxjBWwPDQFBgXgstxKFv9c",
# "Connection": "keep-alive",
# "Content-Length": 135,
# "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Cookie": "BIDUPSID=B7ACF64C783E3B73645D3323470AB49A; PSTM=1673922626; BAIDUID=B7ACF64C783E3B73CAF9C2B143A72C54:FG=1; BDUSS=3pJeC1YSW9sMTdtWnJYTjFsNGhLWlMzQXBvLXczWDhYZmJWVm1Ldn5hNnBPeVprSVFBQUFBJCQAAAAAAAAAAAEAAACZMXhPwPjWvsPIw8i1xMPD1r0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmu~mOprv5jU; BDUSS_BFESS=3pJeC1YSW9sMTdtWnJYTjFsNGhLWlMzQXBvLXczWDhYZmJWVm1Ldn5hNnBPeVprSVFBQUFBJCQAAAAAAAAAAAEAAACZMXhPwPjWvsPIw8i1xMPD1r0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmu~mOprv5jU; MCITY=-75%3A; BDRCVFR[feWj1Vr5u3D]=mk3SLVN4HKm; delPer=0; BA_HECTOR=a48l2ga4a0ag2k81a18h2k6o1i4k9v31m; ZFY=CAFlEcS29dgJPDuArbb39lOlNBjmuCKJ9lY8MXuvcQY:C; BAIDUID_BFESS=B7ACF64C783E3B73CAF9C2B143A72C54:FG=1; BDRCVFR[V-StjDknnVC]=mk3SLVN4HKm; H_PS_PSSID=; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; PSINO=6; APPGUIDE_10_0_2=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1682583783; BCLID=10152727270919425040; BCLID_BFESS=10152727270919425040; BDSFRCVID=PWIOJexroG07VWbfsGZCMPjsK_weG7bTDYrE1k12eFgi6oAVFe3JEG0Pts1-dEu-S2OOogKKXgOTHw0F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; BDSFRCVID_BFESS=PWIOJexroG07VWbfsGZCMPjsK_weG7bTDYrE1k12eFgi6oAVFe3JEG0Pts1-dEu-S2OOogKKXgOTHw0F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tRAOoC_-tDvtHJrwMDTD-tFO5eT22-usLNvA2hcHMPoosIt63lJDbRt1W4buQPTeWaOf0l05KfbUotoHDt4aD4LzbUuq2Mop3DIeaq5TtUJMqIDzbMohqqJXXPnyKMniyIv9-pn5tpQrh459XP68bTkA5bjZKxtq3mkjbPbDfn028DKu-n5jHjcLDaQP; H_BDCLCKID_SF_BFESS=tRAOoC_-tDvtHJrwMDTD-tFO5eT22-usLNvA2hcHMPoosIt63lJDbRt1W4buQPTeWaOf0l05KfbUotoHDt4aD4LzbUuq2Mop3DIeaq5TtUJMqIDzbMohqqJXXPnyKMniyIv9-pn5tpQrh459XP68bTkA5bjZKxtq3mkjbPbDfn028DKu-n5jHjcLDaQP; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1682584037; ab_sr=1.0.1_NTgzZmQwZmNlMDZmMWY4NTlkYWIxYmVjNTg1YjExMWJhN2MzYzRjYTIwZTJkMGUzZjQ2NDNhNTVhNjUxNzI2ODNhMWFmNmY3ZmVjMDNjNzNkMzEzM2Q5ZjU2Mjg3ZWI3ZmM4MzY2ZjkwYzZiMWJiNzc5NWFmMzIxYTFhNWE0MDdhODI0N2IyNTA1Njg0NGNmZmYwNWMyZWYzMzZlOTljMTFhZTBiNDQxZGJlZmZiMWNhZmFiNjc1MDU4NjRjM2Vm",
# "Host": "fanyi.baidu.com",
# "Origin": "https://fanyi.baidu.com",
# "Referer": "https://fanyi.baidu.com/?fr=pcPinzhuan",
# "sec-ch-ua": '"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"',
# "sec-ch-ua-mobile": "?0",
# "sec-ch-ua-platform": '"Windows"',
# "Sec-Fetch-Dest": "empty",
# "Sec-Fetch-Mode": "cors",
# "Sec-Fetch-Site": "same-origin",
# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
# "X-Requested-With": "XMLHttpRequest",
}
# 定义参数集合
data = {
"from": "en",
"to": "zh",
"query": "hello",
"transtype": "realtime",
"simple_means_flag": 3,
"sign": "54706.276099",
"token": "f314b18af4bb40ssb12a65e08adcfe194c",
"domain": "common",
}
# post请求的参数必须进行编码
data_unicode = urllib.parse.urlencode(data).encode("utf-8")
print(data_unicode)
request = urllib.request.Request(url=url, data=data_unicode, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
print(content)
print(type(content))
# str 转 json
obj = json.loads(content)
print(obj)
八、ajax的get请求
- 豆瓣电影的第一页
# 引入urllib
import urllib.request
import urllib.parse
# 找到网页的源码
url = "https://movie.douban.com/j/chart/top_list?"
# 定义参数集合
data = {
"type": "30",
"interval_id": "100:90",
"action": "",
"start": "0",
"limit": "20",
}
# 对中文进行unicode编码
data_unicode = urllib.parse.urlencode(data)
print(data_unicode)
url = url + data_unicode
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
print(content)
# 写入文件1
file = open('douban_page1.txt','w',encoding='utf-8')
file.write(content)
# 写入文件2
with open('douban_page1.txt','w',encoding='utf-8') as fp:
fp.write(content)
- 豆瓣电影的前10页
# 引入urllib
import urllib.request
import urllib.parse
def create_request(page):
url = "https://movie.douban.com/j/chart/top_list?"
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
# 定义参数集合
data = {
"type": "30",
"interval_id": "100:90",
"action": "",
"start": str(page * 20),
"limit": 20,
}
# 对中文进行unicode编码
data_unicode = urllib.parse.urlencode(data)
url = url + data_unicode
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
return content
for page in range(10):
contents=create_request(page)
# 写入文件1
file = open('douban_page10.txt', 'a', encoding='utf-8')
file.write(contents + '\n')
file.close()
九、ajax的post请求
- 实例:肯德基餐厅查询
# 引入urllib
import urllib.request
import urllib.parse
def create_request(page):
url = "http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname"
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
# 定义参数集合
data = {
"cname": "重庆",
"pid": "",
"pageIndex": (page+1),
"pageSize": 10,
}
# 对中文进行unicode编码
data_unicode = urllib.parse.urlencode(data).encode('utf-8')
request = urllib.request.Request(url=url,data=data_unicode, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
return content
if __name__=='__main__':
for page in range(10):
contents = create_request(page)
# 写入文件1
file = open('kengdeji_page'+str(page)+'.txt', 'w', encoding='utf-8')
file.write(contents + '\n')
file.close()
十、异常【URLError\HTTPError
】
- 简介:
- 1.HTTPError类是URLError类的子类
- 2.导入的包 urllb.error.HTTPError urllib.error.URLError
- 3.http错误: http错误是针对浏览器无法连接到服务器而增加出来的错误提示。引导并告诉浏览者该页是哪里出了问题。
- 4.通过urllib发送请求的时候,有可能会发送失败,这个时候如果想让你的代码更加的健壮,可以通过try-except进行捕获异常,异常有两类,URLError HTTPError
# 引入urllib
import urllib.request
import urllib.error
url = "https://blog.csdn,net/sulixu/article/details/119818949"
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
try:
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
# 获取相应的内容
content = response.read().decode("utf-8")
except urllib.error.HTTPError:
print('系统正在升级')
except urllib.error.URLError:
print('地址栏错误')
十一、cookie登录
referer 防盗链
访问中【headers或handler处理器方式】 携带 cookie参数
十二、handler处理器
定制更高级的请求头
动态cookie
- 实例:获取网页源码
# 引入urllib
import urllib.request
url = "http://www.baidu.com"
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
handler = urllib.request.HTTPHandler()
opener = urllib.request.build_opener(handler)
response = opener.open(request)
# 获取相应的内容
content = response.read().decode("utf-8")
print(content)
十三、代理
- 代理的常用功能
- 1.突破自身IP访问限制,访问因外站点
- 2.访问一些单位或团体内部资源
- 3.提高访问速度
- 通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度
- 4.隐藏真实IP
- 上网者也可以通过这种方法隐藏自己的IP,免受攻击。
- 代码配置代理
- 创建Reuqest对象
- 创建ProxyHandler对象
- 用handler对象创建opener对象
- 使用opener.open函数发送请求
IP 地址 不对就访问不了
# 引入urllib
import urllib.request
url = "http://www.baidu.com"
# 请求对象定制[是为了解决反扒的第一种手段]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=headers)
# 代理
# proxies = {}
proxies = {"http": "182.150.110.85"}
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
# 获取相应的内容
content = response.read().decode("utf-8")
print(content)
十四、代理池
- 随机选择
import random
demo = [{"k": "1"}, {"k": "2"}, {"k": "3"}, {"k": "4"}, {"k": "5"}]
end = random.choice(demo)
print(end)