# 爬取药监局网站中企业的备案信息
爬虫主要分为以下几个阶段
发起请求
获取网站信息
解析网页内容
本地化储存
本案例主要针对前两步,不涉及解析内容,且待下回分说
爬取的信息是通过 ajax 动态加载的,所以不能够只对网页 url 发送请求。
本案例中需要对药监局官网中 ajax 发送的 json 数据进行提取,得到详细的 id,再根据 id 得到各个药品的详情网页 url,具体步骤如下
先打开开发者工具查看当前 Elements,看网页信息是否动态发送,确 Element 中不含我们需要的信息认后,打开 XHR,依次查看对应的请求(一般很少,太多的话及时暂停就好),找到我们需要的请求,复制相应传输数据的 url
在写爬虫之前先对整个需求进行分析,我们需要获取的是各个药品公司的详情信息,每个信息存储在一个详情页面中,详情页面需要通过公司 id 访问,公司 id 可以由主页面得到,所以我们需要使用到的数据有,每个公司的 id,每个公司的详情信息,所以分别建立两个数组存储两个信息
all_data_list = [] # 企业信息
id_list = [] # 公司id
1
2
2
刚刚复制的链接为我们请求信息的发送的 url,再加上简单的 UA 代理,最基本的请求对象包装就形成了
url = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.35 Safari/537.36'
}
1
2
3
4
5
2
3
4
5
再来确定我们需要的企业信息个数,这里做一个简单的分页爬取,假设我们要爬取前 6 页的企业信息,打开 ajax 请求 response 把鼠标移动到最后,发现有几个传递的参数,复制,贴贴到 pycharm 中。
for page_number in range(1,6): ## 分页提取
page_number = str(page_number)
param = {
'on':' true',
'page':page_number,
'pageSize':' 15',
'productName':'',
'conditionType':' 1',
'applyname':'',
'applysn':'',
}
## 这里可以使用pycharm中的正则匹配一步加上所有的'',使用ctrl+R快捷键
## 匹配表达式(.*):(.*?)匹配'$1':'$2',点击replace all
##
response = requests.post(url=url,headers=headers,data=param) # requests对象封装并发送请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
获取 id,并且存储到 id_list 中,方便之后读取
## 不要用json.dump()莫名报错,对象缺失
json_ids = json.loads(response.text)['list']
for dic in json_ids:
id_list.append(dic['ID'])
1
2
3
4
5
2
3
4
5
我们获得 id_list 之后,获取企业详情数据,操作与上几乎相同,先拼接 url,再封装字典对象传递 id,发送请求,本地加载存储
for id in id_list:
post_url = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById"
param_sub = {
'id': id,
}
detail_json = json.loads(requests.post(url=post_url,headers=headers,data=param_sub).text)
all_data_list.append(detail_json)
with open('./药监局企业信息.json','w',encoding='utf-8') as fp:
json.dump(all_data_list,fp=fp,ensure_ascii=False)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
完成!!!