Urllib
如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,沿着蜘蛛网抓取自己想要的数据
一、反爬手段
User‐Agent:
User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
代理IP
-
西次代理
-
快代理
-
什么是高匿名、匿名和透明代理?它们有什么区别?
1.使用透明代理,对方服务器可以知道你使用了代理,并且也知道你的真实IP。 2.使用匿名代理,对方服务器可以知道你使用了代理,但不知道你的真实IP。 3.使用高匿名代理,对方服务器不知道你使用了代理,更不知道你的真实IP。
验证码访问
-
打码平台
-
云打码平台
-
超级🦅 动态加载网页 网站返回的是js数据 并不是网页的真实数据 selenium驱动真实的浏览器发送请求 数据加密 分析js代码
二、urllib库使用
-
基本使用
# 使用urllib获取百度首页源码 import urllib.request #定义一个url 就是你访问的网址 url='http://www.baidu.com' # 模拟浏览器发送请求 response=urllib.request.urlopen(url) # 获取响应页面的源码 # read方法 返回是字节形式的二进制数据 # 将二进制数据转为字符串 解码 content=response.read().decode('utf-8') # 打印数据 print(content)
-
一个类型 6个方法
# 使用urllib获取百度首页源码 import urllib.request url='http://www.baidu.com' # 模拟浏览器发送请求 response=urllib.request.urlopen(url) # 一个类型 response # <class 'http.client.HTTPResponse'> print(type(response)) # 按照一个字节去读 read #content=response.read().decode('utf-8') # 按行读 readline//readlines #content2=response.readlines() # 返回状态码 如果是200, 就OK print(response.getcode()) # 返回url地址 print(response.geturl()) # 获取一个状态信息 print(response.getheaders())
-
下载资源
import urllib.request #下载网页 url_page='http://www.baidu.com' # 包含两个参数,下载路径和文件地址 """ urllib.request.urlretrieve(url_page,'baidu.html') """ #下载图片 """ url_img='路径' urllib.request.urlretrieve(url=url_img,filename='鸽鸽.jpg') """ #下载视频 url_video='https://vd2.bdstatic.com/mda-kak74qxwrp92muqj/sc/mda-kak74qxwrp92muqj.mp4?v_from_s=hkapp-haokan-hnb&auth_key=1691953018-0-0-ca0445307d22df4d842c0996e5b43595&bcevod_channel=searchbox_feed&pd=1&cr=2&cd=0&pt=3&logid=3418653319&vid=13218590079052061566&klogid=3418653319&abtest=111803_2-112162_4' urllib.request.urlretrieve(url=url_video,filename='ji.mp4')
-
三、请求对象的定制
UA介绍:User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等
语法:request = urllib.request.Request
()
import urllib.request
url='https://www.baidu.com'
#url的组成
# https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
#http/https www.baidu.com 80/443 s wd=周杰伦
# 协议 主机 端口号 路径 参数 锚点
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36'
}
# 请求对象的定制
# urlopen方法不能储存字典 所以headers不能传递出去
request=urllib.request.Request(url=url,headers=headers)
response=urllib.request.urlopen(request)
content=response.read().decode('utf-8')
print(content)
四、编解码
1、get请求方式:urllib.parse.quote()
import urllib.request
import urllib.parse
# 需求 获取 https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=2&tn=baiduhome_pg&wd=蔡徐坤 网页源码
url='https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=2&tn=baiduhome_pg&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/115.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)
2、get请求方式:urllib.parse.urlencode()
# 应用 请求多个参数
# https://www.baidu.com/s?wd=蔡徐坤&sex=男
import urllib.parse
import urllib.request
data={
'wd':'蔡徐坤',
'sex':'男'
}
base_url='https://www.baidu.com/s?'
new_data=urllib.parse.urlencode(data)
url=base_url+new_data
headers={'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.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)
3、post请求方式
#eg:百度翻译 post请求
import urllib.request
import urllib.parse
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/115.0.0.0 Safari/537.36'
}
keyword = input('请输入您要查询的单词:')
data = {
'kw':keyword
}
#post 请求参数 必须进行编码 变成utf-8形式d
data=urllib.parse.urlencode(data).encode('utf-8')
request=urllib.request.Request(url=url,data=data,headers=headers)
response=urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
import json
obj=json.loads(content)
print(obj)
-
百度详细翻译
import urllib.request import urllib.parse url='https://fanyi.baidu.com/v2transapi?from=en&to=zh' headers={ 'Accept':'*/*', # 'Accept-Encoding':'gzip, deflate, br', 'Accept-Language':'zh-CN,zh;q=09,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', 'Acs-Token':'16 'Content-Type':'applicatin/x-www-form-urlecoded; charset=UTF-8', 'Host':'fanyi.baidu.com', 'Origin':'https://fanyi.baidu.com', 'Referer': 'https://fanyi.baidu.com/?a', 'Sec-Ch-Ua':'"Not/A)Brand";="99", "Microsoft dge";v="115", "Chrmium";v="115"', 'Sec-Ch-Ua-Mobile':'?0', 'Sec-Ch-Ua-Platform':'Widows', 'Sec-Fetch-Dest':'empt', 'Sec-Fetch-Mode':'cos', 'Sec-Fetch-Site':'same-origin', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', 'X-Requested-With':'XMLHttpRequest' } data={ 'from': 'en', 'to': 'zh', 'query': 'love', 'transtype': 'translang', 'simple_means_flag':' 3', 'sign': '198772.518981', 'token': '7ee9e045de03b886d01b79c131d26d48', 'domain': 'common', 'ts': '1692018324541', } #post 请求参数必须进行编码,并且要调用encode方法 data = urllib.parse.urlencode(data).encode('utf-8') #请求对象的定制 request=urllib.request.Request(url=url,data=data,headers=headers) response=urllib.request.urlopen(request) content=response.read().decode('utf-8') print(content) import json obj=json.loads(content) print(obj)
五、ajax的get请求
-
get请求豆瓣电影第一页数据
#get请求 # 获取豆瓣第一页数据保存起来 import urllib.request url='https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20' headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36' } # 1.请求对像的定制 request=urllib.request.Request(url=url,headers=headers) # 2.获取响应的数据 response=urllib.request.urlopen(request) content=response.read().decode('utf-8') # print(content) #3.下载到本地 open方法默认使用gbk编码 fp=open('douban.json','w',encoding='utf-8') fp.write(content)
-
get请求豆瓣电影前十页
#https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=0&limit=20
import urllib.request
import urllib.parse
#https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=20&limit=20
#https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=40&limit=20
url='https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&'
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36'
}
def get_content(i):
data={
'start' : (i-1)*10,
'limit' : 20
}
data=urllib.parse.urlencode(data)
url1 = url + data
print(url1)
request = urllib.request.Request(url=url, headers=headers)
reponse = urllib.request.urlopen(request)
content = reponse.read().decode('utf-8')
return content
while True:
try:
a = eval(input('请输入起始页:'))
b = eval(input('请输入终止页:'))
for i in range(a, b + 1):
fp = open('douban第' + str(i) + '页.json', 'w', encoding='utf-8')
content = get_content(i)
fp.write(content)
break
except:
print('输入错误,重新输入')
六、ajax的post请求
post请求肯德基重庆门店信息
import urllib.parse
import urllib.request
import json
# cname: 重庆 cname: 重庆
# pid: pid:
# pageIndex: 1 pageIndex: 2
# pageSize: 10 pageSize: 10
#http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
base_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/115.0.0.0 Safari/537.36'
}
def get_content(page):
data = {
'cname': '重庆',
'pid':'',
'pageIndex': page,
'pageSize': '10',
}
data=urllib.parse.urlencode(data).encode('utf-8')
request=urllib.request.Request(url=base_url,data=data,headers=headers)
response=urllib.request.urlopen(request)
content=response.read().decode('utf-8')
return content
if __name__ == '__main__':
start_page=eval(input('请输入起始页:'))
end_page=eval(input('请输入终止页:'))
for page in range(start_page,end_page+1):
content=get_content(page)
try:
fp = open('kfc第'+str(page)+'页.json','w',encoding='utf-8')
fp.write(content)
except:
print('error')
七、URLError\HTTPError
eg:
import urllib.request
import urllib.error
# url='https://blog.csdn.net/sulixu/article/details/1198189491'
url='https://www.douban111.com'
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.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')
print(content)
except urllib.error.HTTPError :
print("网址出现问题")
except urllib.error.URLError:
print('ji')
八、微博cookie登录
# 适用场景: 数据采集的时候 需要绕过登录 然后进入某个界面
# 个人信息页面是utf-8 报错编码错误,因为没有进入个人信息页面 而是跳转到了登录界面
# 登录界面是GB2312 所以报错
# 什么情况下访问不成功
# 因为请求头的信息不够 所以访问不成功
import urllib.request
url='https://weibo.cn/786357/info'
headers={
#cookie 中携带了我的登录信息 如果有登录之后的cookie 就可以携带cookie进入任何页面
"Cookie": " ",
# referer 判断当前路径是不是上一个路径进来的一般情况下做图片防盗链
"Referer": "https://weibo.cn",
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.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')
fp=open('weibo.html','w',encoding='utf-8')
fp.write(content)
九、Handler处理器
-
基本使用
# 使用handler 来访问百度 获取网页源码 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/115.0.0.0 Safari/537.36' } request=urllib.request.Request(url=url,headers=headers) # handler build_opener open # 获取handler对象 handler =urllib.request.HTTPHandler() # 获取opener对象 opener=urllib.request.build_opener(handler) # 调用open方法 response=opener.open(request) content=response.read().decode('utf-8') print(content)
-
使用代理
使用代理池
import urllib.request
import random
url='http://www.baidu.com/s?wd=ip'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203'
}
request=urllib.request.Request(url=url,headers=headers)
# 代理池
proxies_pool=[
{'http':'183.236.123.242:8060'},
{'http':'123.169.38.79:9999'},
]
proxies=random.choice(proxies_pool)
# 获取handler对象
handler =urllib.request.ProxyHandler(proxies=proxies)
# 获取opener对象
opener=urllib.request.build_opener(handler)
# 调用open方法
response=opener.open(request)
content=response.read().decode('utf-8')
with open('ip.html','w',encoding='utf-8') as fp:
fp.write(content)