Python学习记录-项目案例实现:爬虫篇 04

这次为大家带来的是一个综合性较强的小项目,该项目流程较多且不需要用数据解析也能完成。由于该项目涉及到他人的隐私信息,故不会有对应信息的截图,敬请理解!


项目来源

本项目来源B站UP主路飞学城视频:视频链接点这里

项目需求

  • 爬取所有生产化妆品的公司的企业名称和生产许可证编号
  • 爬取每一家企业的详情页的生产许可证信息详细数据

具体分析

1. 指定URL

1.1 初始页面目标URL的获取

打开药监局化妆品生产许可信息管理系统服务平台:http://scxk.nmpa.gov.cn:81/xk/
打开抓包工具对页面发送请求,在响应数据中尝试搜索具体公司名称发现为空,初步判断企业名称等数据为ajax请求,打开对应数据抓取工具,再次发请求后拿到对应的数据包。
请求到的数据包
在headers板块中可获得对应需求1的目标URL,将其粘贴至代码段即可。在该板块中可以继续获得如下信息:

  • 发送的请求为post请求
  • 得到的响应数据为json格式
  • post请求携带的参数有:

on: true
page: 1
pageSize: 15
productName:
conditionType: 1
applyname:
applysn:

1.2 详情页面目标URL的获取

下面随机点开一家公司的详情页,以首页的第一家公司为例。
详情页URL:http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=2bb25030a84e4c13a1dfff05d837cba1
再打开两家公司的URL:

通过对比能够很明显看出三者的区别仅为后面id参数值不同,据此可猜测这个id就是每一家公司详情页URL的一个参数。
下面利用抓包工具对第一家公司详情页发请求,在拿到的数据包里的响应数据中查找公司名称等数据,发现依旧无结果返回,则这些数据极有可能也存在一个ajax包里。打开对应抓包工具,再次发请求,拿到对应数据包。
请求到的数据包
在headers板块中即可获得需求2的URL,同时还可以获取以下信息:

  • 发送的请求同样为post请求
  • 返回的响应数据为json格式
  • post请求携带的参数为企业的id值

2. UA伪装

依旧与以前一样进行UA伪装即可,此处不再写出

3. 对概览页目标信息的获取

根据前面的分析可初步得知,为了爬取到我们所需要的信息,首先需要获取每一家企业的id值。用抓包工具获取在概览页中请求到的ajax包里的响应数据,并用json解析器解析后,得如下结果(以下只列出一部分结果,数目太多占篇幅)

{
“filesize”: “”,
“keyword”: “”,
“list”: [{
“ID”: “2bb25030a84e4c13a1dfff05d837cba1”,
“EPS_NAME”: “艾一生命科技(广东)有限公司”,
“PRODUCT_SN”: “粤妆20210025”,
“CITY_CODE”: null,
“XK_COMPLETE_DATE”: {
“date”: 21,
“day”: 4,
“hours”: 0,
“minutes”: 0,
“month”: 0,
“nanos”: 0,
“seconds”: 0,
“time”: 1611158400000,
“timezoneOffset”: -480,
“year”: 121
},
“XK_DATE”: “2026-01-20”,
“QF_MANAGER_NAME”: “广东省药品监督管理局”,
“BUSINESS_LICENSE_NUMBER”: “91440300MA5F0H5AXJ”,
“XC_DATE”: “2021-01-21”,
“NUM_”: 1
},

可见所有数据都封装在一个字典中,而公司对应的信息则封装在字典下的’list’键值的value值中。该value值为一个列表,里面封装了一个字典,只需将该字典里的ID对应的value值提取出来即完成了信息的获取。
表现在代码中,即为

ids_list = []  # 存储企业对应的id值
home_json = requests.post(url=url, data=data_home, headers=header).json()
for dic in home_json['list']:
    ids_list.append(dic['ID'])

4. 对详情页目标信息的提取

获取了id值后,就获取了详情页目标URL的参数,接下来就可以对详情页对应的URL发请求了。由于在之前将概览页展示的所有企业的id值存储在一个列表中,那么通过循环即可实现一一对这些公司的详情页对应URL发请求,表现在代码中,即为

final_list = []  # 存储最终获取的数据
url_post = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
for id in ids_list:
    data_detail = {'id': id}
    detail_json = requests.post(url=url_post, data=data_detail, headers=header).json()
    final_list.append(detail_json)

5. 持久化存储

因为获取的响应数据为json格式,故调用json模块对获取的数据进行存储。

fp = open('./企业信息.json', 'w', encoding='utf-8')
json.dump(final_list, fp=fp, ensure_ascii=False)

6. 翻页操作

以上进行的只是对概览页第一页进行数据获取,那么要想进行分页操作要怎么实现呢?
在对概览页目标URL的捕获阶段,我们使用抓包工具获取了该post请求携带的参数,其中的参数page: 1即表示当前为第一页概览页,只要改变这个value值即可实现翻页操作,具体在完整代码中展示。

项目代码

# -*- coding: utf-8 -*-
# @author   : QIN
# @time     : 2021/1/11 13:04
# @function :
import requests
import json


if __name__ == '__main__':
    url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
    header = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
    }
    ids_list = []  # 存储首页企业的id数据
    final_list = []  # 全部数据存储
    for page in range(1, 6):  # 一共有365页,这里只爬取前五页
        page = str(page)
        data_home = {
            'on': 'true',
            'page': page,
            'pageSize': '15',
            'productName': '',
            'conditionType': '1',
            'applyname': '',
            'applysn': '',
        }
        home_json = requests.post(url=url, data=data_home, headers=header).json()
        for dic in home_json['list']:
            ids_list.append(dic['ID'])
        # print(ids_list)
    url_post = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
    for id in ids_list:
        data_detail = {'id': id}
        detail_json = requests.post(url=url_post, data=data_detail, headers=header).json()
        final_list.append(detail_json)
    fp = open('./企业信息.json', 'w', encoding='utf-8')
    json.dump(final_list, fp=fp, ensure_ascii=False)
    print('数据下载成功!')

运行结果

由于这里只爬取到第五页,这里我们将第五页最后一家公司的详情页点开进行核对,发现爬取到的信息无误,即本案例完成!

注意事项

本案例更加接近日常生活中的爬虫需求,在本例中进行了两次请求的发送,其中第一次请求发送是为了服务第二次请求发送。在传参的时候,注意看仔细不要漏,否则不会请求出结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值