1. requets模块初始
- 环境安装
- pip install requests
- 使用流程
- 指定url
- UA伪装
- 请求参数处理
- 基于requests模块发起请求
- 获取响应对象中的数据值
- 持久化存储
- 指定url
2. requests案例实战
2.1 需求:爬取搜狗首页的页面数据
# 导包
import requests
# step1:指定url
url = 'https://www.sogou.com/'
# step2:发起请求:使用get方法发起get请求,该方法会返回一个响应对象。参数url表示请求对应的url
response = requests.get(url=url)
# step3:获取响应数据:通过调用响应对象的text属性,返回响应对象中存储的字符串形式的响应数据(页面源码数据)
page_text = response.text
print(page_text)
# step4:持久化存储
with open('./result/sogou.html','w',encoding='utf-8') as fp:
fp.write(page_text)
print("爬取数据结束!!!")
2.2 需求:爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
反爬机制:
- UA:User-Agent(请求载体的身份标识)
- UA检测:门户网站的服务器检测对应请求的载体身份标识,如果检测到请求的载体身份标识为某一款浏览器,说明该请求是一个正常的请求。但是,如果检测到到请求的载体身份标识不是基于某一款浏览器的,则表示该请求为不正常的请求(爬虫),服务器端很有可能拒绝该次请求
对应的反反爬策略
- UA伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器
import requests
if __name__ == '__main__':
# UA伪装:将对应的User-Agent封装到一个字典中
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}
url = 'https://www.sogou.com/web'
# 处理URL携带的参数:封装到字典中
kw = input('enter a word:')
param = {
"query": kw
}
# 对指定的url发起的请求对应的url是携带参数的,并且请求过程中处理了参数,headers是头信息
response = requests.get(url=url, params=param, headers=headers)
page_text = response.text
fileName = './result/' + kw + '.html'
with open(fileName, 'w', encoding='utf-8') as fp:
fp.write(page_text)
print(fileName, "保存成功!!!")
2.3 需求:破解百度翻译
- post请求(携带了参数)
- 响应数据是一组json数据
import requests
import json
if __name__ == '__main__':
# 1. 指定url
post_url = 'https://fanyi.baidu.com/sug'
# 2. 进行UA伪装
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}
# 3. post请求参数处理(同get请求一致)
word = input('enter a word:')
data = {
'kw': word
}
# 4. 发起请求
response = requests.post(url=post_url, data=data, headers=headers)
# 5. 获取响应数据:json()方法返回的是obj(如果确认响应数据是jdoson类型的,才可以使用json())
dic_obj = response.json()
# print(dic_obj)
# 6. 进行持久化存储
fileName = './result/' + word + '.json'
fp = open(fileName, 'w', encoding='utf-8')
json.dump(dic_obj, fp=fp, ensure_ascii=False) # 返回的是中文的时候,不能用ascii码
print('over!!!')
2.4 需求:爬取豆瓣电影分类排行榜中的电影详情数据
豆瓣电影地址:https://movie.douan.com/
import requests
import json
if __name__ == '__main__':
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/96.0.4664.45 Safari/537.36'
}
param = {
'type': '24',
'interval_id': '100:90',
'action': '',
'start': '0', # 从库中第几部电影开始去取
'limit': '20' # 一次请求取出的电影个数
}
response = requests.get(url=url, params=param, headers=headers)
list_data = response.json()
fp = open('./result/douban_movie.json', 'w', encoding='utf-8')
json.dump(list_data, fp=fp, ensure_ascii=False)
print('finished!!!')
2.5 需求:爬取肯德基餐厅查询中指定地点的餐厅数据
地址:http://www.kfc.com.cn/kfccda/index.aspx
import requests
import json
def KFC_spider(url=None, keyword='北京'):
"""
根据关键字爬取KFC餐厅信息
:param url:url链接
:param keyword:地址关键词
"""
if url is None:
print("url should not be None!")
return
# 1. 指定post请求的url(通过抓包进行获取)
url = url
# 2. 进行UA伪装,相关的头信息封装在字典结构中
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}
# 3. post请求参数处理(同get请求一致)(从抓包工具中获取)
params = {
'cname': '',
'pid': '',
'keyword': keyword,
'pageIndex': '1',
'pageSize': '10'
}
# 4. 发送请求
response = requests.post(url=url, data=params, headers=headers)
# 5. 获取响应数据:json()方法返回的是obj(如果确认响应数据是jdoson类型的,才可以使用json())
page_text = response.json()
# print(page_text)
# 6. 持久化存储
fileName = './result/' + keyword + '.json'
fp = open(fileName, 'w', encoding='utf-8')
json.dump(page_text, fp=fp, ensure_ascii=False) # 返回的是中文的时候,不能用ascii码
# 打印数据
for data in page_text["Table1"]:
print(
"序号:{}, 店名:{}, 地址:{}, 信息:{}".format(data["rownum"], data["storeName"], data["addressDetail"], data["pro"]))
print("{}KFC餐厅信息爬取成功!".format(keyword))
if __name__ == '__main__':
# 指定post请求的url
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
# 输入地址关键词
keyword = input("enter a word: ")
# 爬取餐厅信息
KFC_spider(url=url, keyword=keyword)
运行结果:
2.6 需求:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据
地址:http://scxk.nmpa.gov.cn:81/xk/
-
动态加载数据
-
首页中对应的企业信息数据是通过ajax动态请求到的
-
通过对详情页url观察发现:
- url的域名都是一样的,只有携带的参数(id)不一样
- id值可以从首页对应的ajax请求到的json串中获取
- 域名和id值拼接出一个完整的企业对应的详情 页的url
-
详情页的企业详情数据也是动态加载出来的
-
随机找到两个详情页的url地址
-
http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById
-
http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById
-
-
观察后发现:
- 所有的post请求的url都是一样的,只有参数id值是不同的
- 如果可以批量获取多家企业的id后,就可以 将id和url形成一个完整的详情页对应详情数据的ajax请求的url
-
import requests
import json
if __name__ == '__main__':
# 批量获取不同企业的id值
# UA伪装,相关的头信息封装在字典结构中
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}
id_list = [] # 存储企业的id
all_data_list = [] # 存储所有企业的详情数据
# 指定post请求的url
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
# 参数封装
num_page = 6
for page in range(1, num_page):
page = str(page)
# 参数的封装
data = {
'on': 'true',
'page': page,
'pageSize': '15',
'productName': '',
'conditionType': '1',
'applyname': '',
'applysn': ''
}
# 发送请求
response = requests.post(url=url, data=data, headers=headers)
# 获取响应数据
json_ids = response.json()
for dic in json_ids['list']:
id_list.append(dic['ID'])
print("爬取{}页,获取id数据量:{}".format(num_page - 1, len(id_list)))
# 获取企业详情数据
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
for id in id_list:
data = {
'id': id,
}
response = requests.post(url=post_url, data=data, headers=headers)
detail_json = response.json()
all_data_list.append(detail_json)
# 持久化存储all_data_list
fileName = './result/allData.json'
fp = open(fileName, 'w', encoding='utf-8')
json.dump(all_data_list, fp=fp, ensure_ascii=False) # 返回的是中文的时候,不能用ascii码
print('共获取详情数据{}条'.format(len(all_data_list)))
# print("{}KFC餐厅信息爬取成功!".format(keyword))
print('over!!!')
如果本文对你有帮助,记得“点赞”哦~