Python 爬虫Sutdy
1.基本类库
request(请求)
- 引入
pythonfrom urllib import request
- 定义url路径
pythonurl="http://www.baidu.com"
- 进行请求,返回一个响应对象response
pythonresponse=request.urlopen(url)
- 读取响应体read()以字节形式打印网页源码
pythonresponse.read()
转码
编码 文本--byte encode
解码 byte--文本 decode
python#将上方转为文本 text=response.read().decode("utf-8") # 打印为源码文本显示 print(text)
写入
语法:with open ('文件名','w',设定编码格式) as fp: fp.write(文本) w代表写入
pythonwith open ('命名.html','w',encoding='utf-8') as fp: fp.write(text)
读取
读取响应体内容并转为utf-8格式
pythonresponse.read().decode("utf-8")
- 读取状态
scssresponse.getcode()
- 读取请求路径
scssresponse.geturl()
- 读取响应头
scssresponse.getheaders()
parse(url编码)
在开始网页请求之前需保证编码格式~
- 引入
pythonfrom urllib import parse
使用测试
quote(编码)
python#编码 result=parse.quote("小鲁班")
unquote(解码)
python#解码 result1=parse.unquote("%E9%E1%3E")
- 给多个参数编码方式1 变量名.format()
pythonurl2="http://www.baidu.com?name={}&pwd={}" url1=url2.format(parse.quote('用户名'),parse.quote('密码'))
- 给多个参数编码方式2 urlencode
pythonobj={ "name":"肖", "password":"213123丽华", "age":"五十岁" } base_url="http://www.baidu.com/s?" params=parse.urlencode(obj) url=base_url+params
urlretrieve(便捷的下载方式)
python
request.urlretrieve('图片路径','保存路径')
伪装成浏览器访问的样子
封装一个请求对象
请求对象可以携带除了url之外的一切服务器感兴趣的信息,例如cookie、UA等等...
pythonurl="http://www.baidu.com/" # 定义headers headers={ 'User-Agent':"Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36" } req=request.Request(url=url,headers=header) # 将请求对象传入 response=request.urlopen(req)
2.爬取各种常见的URL
如何找到正确的URL
- 直接获取浏览器的地址栏url
- 地址栏url不是固定,需要手动配置
- 有效地址不在地址栏中,而在Network(网络)中后台加载
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eAY6WTRm-1650877844184)(D:\StudyHard\assets\1650638350731.png)]
- 等等....
URL分为GET POST
返回值分为XML(HTML),JSON
处理post/get请求
案例:抓取百度翻译
找到URL
pythonpost_url="https://fanyi.baidu.com/sug"
POST请求表单参数
pythondata_dict={ "kw":"sogreat" }
请求前需要做一次url编码
pythondata=parse.urlencode(data_dict)
参数必须是bytes
pythondata=data.encode("utf-8")
封装请求对象
pythonrq=erquset.Request(url=post_url,headers={},data=data) response=requset.urlopen(rq) text=response.read().decode('utf-8')
最终结果是个符合JSON格式的字符串
- json格式字符串用json解析
- xml格式字符串用xml解析
进一步解析它转JSON
python# 引入 import json json_obj=json.loads(text,encoding='utf-8') # 打印结果为json格式的数据 print(json_obj) # 并且可进行遍历 for...in for s in json_obj["data"] # data为json数据中的一个属性 print(s) #循环打印出data的每个值
案例:抓取KFC餐厅地址信息
找到请求地址与post请求参数
实现:
python# 肯德基店铺位置 http://www.kfc.com.cn/kfccda/storelist/index.aspx #请求头优先级 UA-->cookie--->Refer--->其他 headers1={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44" } newaddr=input("请输入地址:") KFCurl="http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword" pageindex=1 # 使用循环查出所有的数据~ while True: datas={ "cname":"", "pid":"", "pageIndex": pageindex, "pageSize": 10, "keyword": newaddr } #编译转码 data=parse.urlencode(data) data=data.encode(encoding="utf-8") req1=request.Request(url=url,headers=headers,data=data) response1=request.urlopen(req1) address=response1.read().decode('utf-8') address1=json.loads(address) #转json if len(address1['Table1']) == 0: break #表示没数据了 for addr in address1['Table1']: print(addr) pageindex+=1
优化:使用模块化管理 def 模块名(参数名): 可把它看作封装方法--相当于js的函数
python#请求头优先级 UA-->cookie--->Refer--->其他 headers1={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44" } newaddr=input("请输入地址:") #url对象准备模块 def prepare_url(url,headers,data): #编译转码 data=parse.urlencode(data) data=data.encode(encoding="utf-8") req1=request.Request(url=url,headers=headers,data=data) return req1 #请求数据模块 def request_with_url(reqs): response1=request.urlopen(reqs) address=response1.read().decode('utf-8') return address #对响应内容解析模块 def pare_data(text): address1=json.loads(text) #转json if len(address1['Table1']) == 0: return 'null' #表示没数据了 for addr in address1['Table1']: print(addr) KFCurl="http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword" pageindex=1 # 使用循环查出所有的数据~ while True: datas={ "cname":"", "pid":"", "pageIndex": pageindex, "pageSize": 10, "keyword": newaddr } reqs=prepare_url(KFCurl,headers1,datas) text=request_with_url(reqs) if(pare_data(text)=="null"): break pageindex+=1
案例:抓取百度贴吧信息(get)
python
headers1={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44"
}
#第一页 https://tieba.baidu.com/f?kw=%E6%96%97%E7%BD%97%E5%A4%A7%E9%99%86&ie=utf-8&pn=0
#第二页 https://tieba.baidu.com/f?kw=%E6%96%97%E7%BD%97%E5%A4%A7%E9%99%86&ie=utf-8&pn=50
#第三页 https://tieba.baidu.com/f?kw=%E6%96%97%E7%BD%97%E5%A4%A7%E9%99%86&ie=utf-8&pn=100
#规律:pn=(page-1)*50
start_page=1
end_page=5
input_name="%E6%96%97%E7%BD%97%E5%A4%A7%E9%99%86"#斗罗大陆
for page in range(start_page,end_page+1):
url="https://tieba.baidu.com/f?kw{}=&ie=utf-8&pn={}".format(input_name,(page-1)*50)
request=urllib.request.Request(url=url,headers=headers1)
response=urllib.request.urlopen(request)
text=response.read().decode('utf-8')
file_path="page{}.html".format(page)
with open(file_path,'w',encoding="utf-8") as fp:
fp.write(text)
print(file_path,"下载完毕")
print("所有内容下载完毕")
处理Ajax请求
案例:爬取豆瓣电影动画排行榜
python# 定义headers headers={ 'User-Agent':"Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36" } # 1 0----2 20----3 40----得出:(p-1)*20 # page=input("请输入你要查询动画类型的排行榜前几页") # print(page) base_url="https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&start={}&genres=%E5%8A%A8%E7%94%BB" for p in range(0,4): total=p*20 url=base_url.format(total) req=request.Request(url=url,headers=headers) response=request.urlopen(req) text=response.read().decode('utf-8') #转json json_obj=json.loads(text) #只打印部分属性 for val in json_obj['data']: title=val['title'] rate=val['rate'] print("title:{},rate:{}".format(title,rate))