04实例:爬取药监总局企业详情信息
爬取药监总局企业详情信息
国家药监局化妆品许可证:http://scxk.nmpa.gov.cn:81/xk/
json格式化工具:https://www.bejson.com/
思考:如何判定一张页面中是否存在动态加载的数据
抓包工具进行局部搜索
如果判定出页面中有动态加载的数据如何进行数据的定位?
- 使用抓包工具进行全局搜索
对一个陌生的网站数据进行爬取前一定要判定你爬取的数据是否为动态加载的
分析:
1、网站的首页和企业的详情页的数据都是动态加载出来的
2、分析某一家企业的企业详情数据是怎么来的?
企业详情数据时通过一个ajax请求(post)请求到的。
请求对应的url:http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById
该请求携带了一个参数id:xxdxxx。
结论:
-
每家企业详情页的数据都是通过一个post形式的ajax请求请求到的。
-
每家企业对应的ajax请求的url都一样,请求方式都是post,只有请求参数id的值不一样。
-
只需要获取每一家企业对应的id值即可获取每一家企业对应的详情数据。
3、需要获取每一家企业的id值
思路:每一家企业的id值应该存储在首页对应的相关请求或者响应中。
结论:每一家企业的id值是存储在首页中的某一个ajax请求对应的响应数据中,只需要将该响应数据中企业的id提取/解析出来后即可。
实现过程
1、导入包和反爬机制
import requests
# 反爬
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55'
}
2、请求到每一家企业对应的id
# 请求到每一家企业对应的id
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
data = {
'on': 'true',
'page': '1',
'pageSize': '15',
'productName':'',
'conditionType': '1',
'applyname':'',
'applysn': '',
}
# 获取到对应ID的字典数据
# 该json()的返回值中有每一家企业的id
data_dic = requests.post(url=url,data=data,headers=headers).json()
# 解析id
for dic in data_dic['list']:
_id = dic['ID']
print(_id)
得到的id:
661fdf3e63ec4fd6af490d9ef8b200c5
50643af5cc284a9da80e60e25559a4ed
be943a788f7c44dbbd492e0b1cdcecc3
07cbfd400eaf49fc8931c1d82e736409
8c5765a865554b4b8346c2a6cc48a31c
54c5c9708f214fdf9f81c19f28ddcace
8751f1c94563449095c4f6c53175c991
b132c7191d864ddc93ab89ad8a5544e6
90a62cbb10014bf890bf271712c39439
45c37984bdcf481bb1cac20e8e787711
726f2fff3c1b4d898b9e05dce8cf33e8
40fe90bcdd99479b80af665bb9b675bb
c0726999d91f434b804ed534902881b0
0bf0d5a733b24f71b3c55ce1b55b4afb
46372e6d83e54f8cbfa8b531db8222a3
3、对每一个id对应的企业详情数据进行捕获(发起请求)
注意:此时还在循环里!
# 对每一个id对应的企业详情数据进行捕获(发起请求)
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
post_data={
'id':_id
}
# 得到详情页面的字典
# json()返回值是某一家企业的详情信息
detail_dic = requests.post(url=post_url,data=post_data,headers=headers).json()
company_title = detail_dic['epsName']
address = detail_dic['epsAddress']
fp.write(company_title+':'+address+'\n')
print(company_title,'爬取成功!')
完整代码
import requests
# 反爬
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55'
}
fp = open('./company_detail.txt','w',encoding='utf-8')
# 请求到每一家企业对应的id
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
data = {
'on': 'true',
'page': '1',
'pageSize': '15',
'productName':'',
'conditionType': '1',
'applyname':'',
'applysn': '',
}
# 获取到对应ID的字典数据
# 该json()的返回值中有每一家企业的id
data_dic = requests.post(url=url,data=data,headers=headers).json()
# 解析id
for dic in data_dic['list']:
_id = dic['ID']
# print(_id)
# 对每一个id对应的企业详情数据进行捕获(发起请求)
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
post_data={
'id':_id
}
# 得到详情页面的字典
# json()返回值是某一家企业的详情信息
detail_dic = requests.post(url=post_url,data=post_data,headers=headers).json()
company_title = detail_dic['epsName']
address = detail_dic['epsAddress']
fp.write(company_title+':'+address+'\n')
print(company_title,'爬取成功!')
fp.close()
最后的结果会输出。。。。。爬取成功!
然后生成一个对应的company_detail.txt来保存数据。
(一些fiddler的信息,暂时用不到)
拓展
之前的实例只能爬取当前页面上的数据,现在拓展以下来爬取1-5页的数据,可以看到,对应的字典中有page,所有只要指定一个参数就行,然后做个循环,
for page in range(1,6):
# 请求到每一家企业对应的id
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
data = {
'on': 'true',
'page': str(page),
'pageSize': '15',
'productName':'',
'conditionType': '1',
'applyname':'',
'applysn': '',
}
......................
完整代码:
import requests
# 反爬
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55'
}
fp = open('./tuozhan.txt','w',encoding='utf-8')
for page in range(1,6):
# 请求到每一家企业对应的id
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
data = {
'on': 'true',
'page': str(page),
'pageSize': '15',
'productName':'',
'conditionType': '1',
'applyname':'',
'applysn': '',
}
# 获取到对应ID的字典数据
# 该json()的返回值中有每一家企业的id
data_dic = requests.post(url=url,data=data,headers=headers).json()
# 解析id
for dic in data_dic['list']:
_id = dic['ID']
# print(_id)
# 对每一个id对应的企业详情数据进行捕获(发起请求)
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
post_data={
'id':_id
}
# 得到详情页面的字典
# json()返回值是某一家企业的详情信息
detail_dic = requests.post(url=post_url,data=post_data,headers=headers).json()
company_title = detail_dic['epsName']
address = detail_dic['epsAddress']
fp.write(company_title+':'+address+'\n')
print(company_title,'爬取成功!')
fp.close()
最后的思考
解决了我很久的疑惑,如果要翻页,要怎么爬数据
对之前的代码进行了进一步理解
今天豆瓣把我放出来了,等等去爬10万条评论试试