开始之前先来简单了解一下get请求和post请求的区别
get参数会放在url中,所以隐私性,安全性较差
post请求没有的长度限制,请求数据是放在body中
不管在爬取get请求还是post请求都需要找到url、headers(请求头)、data(参数)
post请求
本次实验选取的为爬取肯德基餐厅信息的前n页数据
import urllib.request
import urllib.parse
#定义需要的参数
def creat_request(page):
#找到的地址
base_url='http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
#需要传的参数,该数据来源为From Data
data={
'cname': '北京',
'pid': '',
'pageIndex': page,
'pageSize': '10',
}
#请求头,请求头不同服务器可能需要的参数不一样,这里用到的是ua
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'
}
#将post请求的参数进行拼接和编码,并且调用encode方法
data=urllib.parse.urlencode(data).encode('utf-8')
#封装成对象
req=urllib.request.Request(url=base_url,data=data,headers=headers)
return req
#获取相应数据
def get_content(req):
#模拟浏览器向服务器发送请求
res=urllib.request.urlopen(req)
#获取响应的数据
content=res.read().decode('utf-8')
return content
#写入本地
def down_load(content,page):
with open('kfc_'+str(page)+'.json','w',encoding='utf-8')as f:
f.write(content)
if __name__ == '__main__':
start_page=int(input('请输入起始页码:'))
end_page=int(input('请输入终止页码:'))
for page in range(start_page,end_page+1):
#请求对象定制
req=creat_request(page)
#获取网页源码
content=get_content(req)
#下载
down_load(content,page)
get请求
get请求选取的为爬取豆瓣电影动作片前n页数据
import urllib.parse
import urllib.request
# import urllib.response
#定义需要的参数
def create_request(page):
#基础地址
base_url='https://m.douban.com/rexxar/api/v2/movie/recommend?refresh=0&'
hou_url='&selected_categories=%7B%22%E7%B1%BB%E5%9E%8B%22:%22%E5%8A%A8%E4%BD%9C%22%7D&tags=%E5%8A%A8%E4%BD%9C'
#请求头
headers={
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.9',
'Connection': 'keep-alive',
'Host': 'm.douban.com',
'Origin': 'https://movie.douban.com',
'Referer': 'https://movie.douban.com/explore',
'sec-ch-ua': '"Chromium";v="106", "Google Chrome";v="106", "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-site',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
'Cookie': 'll="118240"; bid=l8xFhRpWBLA; push_noty_num=0; push_doumail_num=0; __utmv=30149280.25197; __gads=ID=1e910eb11225d9d9-22839914ead60086:T=1665141800:RT=1665141800:S=ALNI_MY_0Z6Ii9Wgp8fX5eGG2MuBYJ1J6g; ap_v=0,6.0; __gpi=UID=00000a202fbd0bf9:T=1665141800:RT=1665215635:S=ALNI_MYq-61BLPpqoPoeX2sjJNBw57YO0w; __utma=30149280.571783438.1665141759.1665141759.1665215636.2; __utmz=30149280.1665215636.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; ct=y; __utmc=30149280; __utmt=1; __utmb=30149280.20.10.1665215636',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'
}
#需要传的参数
data={
'start':(page-1)*20,
'count':20
}
#数据拼接
data =urllib.parse.urlencode(data)
#获取url
url=base_url+data+hou_url
#可以打印url查看获取的链接是否正确
#print(url)
#封装成对象
req=urllib.request.Request(url=url,headers=headers)
return req
#获取内容
def get_content(req):
#模拟浏览器向服务器发送请求
res=urllib.request.urlopen(req)
#获取请求转态
print(res.getcode())
#获取响应的数据
content=res.read().decode('utf-8')
return content
#下载
def down_load(page,content):
with open('douban'+str(page)+'.txt','w',encoding='utf-8') as f:
f.write(content)
#程序入口
if __name__ == '__main__':
start_page=int(input('请输入起始页码:'))
end_page=int(input('请输入结束页码:'))
for page in range(start_page,end_page+1):
#请求对象定制
req=create_request(page)
#获取相应数据
content=get_content(req)
#下载
down_load(page,content)
总结:通过上面的对比可以发现,针对get请求和post请求的爬取大致的过程都一致,主要的区别在于post请求在进行data数据的拼接时需要调用encode方法,并且在封装成对象时get请求没有传入data数据,这是因为get请求data的参数会放在URL中,而post请求方式是放在body中的。
上文中对get请求的爬取过程中代码可能出现了错误,看到这篇文章的观众老爷们帮忙纠正一下错误,下面是我遇到的错误的截图
代码运行之后出现这个错误但是网页中给的编码格式也为utf-8,在网上找了不少解决方法,但是没有解决。非常感谢观众老爷们帮忙找一下错误,文章中的其他错误也可以。