(五) 爬虫教程 |Ajax 数据爬取

一、前言

有时候我们在用 requests 抓取页面的时候,得到的结果可能和在浏览器中看到的不一样:在浏览器中可以看到正常显示的页面数据,但是使用 requests 得到的结果并没有,这是因为requests 获取的都是原始的 HTML 文档,而浏览器中的页面则是经过 JavaScript 处理数据后生成的结果,这些数据的来源有多种,可能是通过 Ajax 加载的, 可能是包含在 HTML 文档中的,也可能是经过 JavaScript 和定算法计算后生成的
对于第一种情况,数据加载是一种异步加载方式,原始的页面最初不会包含某些数据,原始页面。加载完后,会再向服务器请求某个接口获取数据,然后数据才被处理从而呈现到网页上,这其实就是发送了一个 Ajax 请求。
照Web 发展的趋势来看,这种形式的页面越来越多 网页的原始 HTML 文档不会包含任何数据,数据都是通过Ajax统一加载后再呈现出来的,这样在 We 开发上可以做到前后端分离,而且降低服务器直接渲染页面带来的压力。所以如果遇到这样的页面,直接利用requests 等库来抓取原始页面,是无法获取到有效数据的,这时需要分析网页后台 接口发送的 jax 请求,如果可以用 requests 来模拟 Ajax 请求,那么就可以成功抓取了。
所以,本章我们的主要目的是了解什么是 jax 及如何去分析和抓取 Ajax 请求

二、什么是Ajax

Ajax ,全称为 Asynchronous JavaScript and XML ,即异步的 JavaScript XML 它不是一门编程
语言,而是利用 JavaScript 在保证页面不被刷新、页面链接不改变的情况下与服务器交换数据并更新部分网页的技术。
对于传统的网页,如果想更新其内容,那么必须要刷新整个页面,但有了 Ajax ,便可以在页面不被全部刷新的情况下更新其内容 在这个过程中,页面实际上是在后台与服务器进行了数据交互,获取到数据之后,再利用 JavaScript改变网页,这样网页内容就会更新了。

  • 我们以CSDN为例子,点击Python,我们向下拉取页面,数据会不断的更新有新的内容,这就是Ajax。
  • 我们注意到页面其实并没有整个刷新,也就意味着页面的链接没有变化,但是网页中却多了新内容,也就是后面刷出来的新微博,这就是通过Ajax获取新数据呈现的过程

在这里插入图片描述

三、Ajax分析方法

我们以前面的CSDN为例,知道拖动刷新的内容由Ajax加载,而且也没的URL没有变化,那么应该到哪里去看这些Ajax请求呢?

  • 1.右击点击检查
  • 2.点Network
  • 3.点击XHR会呈现出XHR数据
  • 4.向下滑动,会有一条条XHR数据更新,这样我们就可以捕获到所有的 Ajax 请求了

在这里插入图片描述

四、实战演练

4.1爬取肯德基餐厅信息

需求:爬取肯德基餐厅查询,指定地点的餐厅数量。
网址:http://www.kfc.com.cn/kfccda/storelist/index.aspx

  • 1.我们可以看到页面是一个text,不是json

在这里插入图片描述

  • 2.看到所需的参数

在这里插入图片描述
代码实现:

# 爬取想要爬取城市的肯德基餐厅信息
import requests

if __name__ == '__main__':
    # 指定url
    url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
    # 动态输入查找的城市
    city = input('请输入您想要查找的城市:')
    # 参数处理
    param = {
        'cname': '',
        'pid': '',
        'keyword': city,        # 城市名称
        'pageIndex': '1',       # 页面
        'pageSize': '10',       # 一页显示多少数据
    }
    # 进行UA伪装
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
    }
    # 获取相应数据
    response = requests.post(url=url,data=param,headers=header)
    # 这个页面是一个text,不是json
    page_text = response.text
    print(page_text)
    print('数据爬取成功!')
    
输出结果:
{"Table":[{"rowcount":65}],"Table1":[{"rownum":1,"storeName":"育慧里","addressDetail":"小营东路3号北京凯基伦购物中心一层西侧","pro":"24小时,Wi-Fi,店内参观,礼品卡","provinceName":"北京市","cityName":"北京市"},{"rownum":2,"storeName":"京通新城","addressDetail":"朝阳路杨闸环岛西北京通苑30号楼一层南侧","pro":"Wi-Fi,店内参观,礼品卡,生日餐会","provinceName":"北京市","cityName":"北京市"},{"rownum":3,"storeName":"黄寺大街","addressDetail":"黄寺大街15号北京城乡黄寺商厦","pro":"Wi-Fi,点唱机,店内参观,礼品卡,生日餐会","provinceName":"北京市","cityName":"北京市"},{"rownum":4,"storeName":"四季青桥","addressDetail":"西四环北路117号北京欧尚超市F1、B1","pro":"Wi-Fi,礼品卡,生日餐会","provinceName":"北京市","cityName":"北京市"},{"rownum":5,"storeName":"亦庄","addressDetail":"北京经济开发区西环北路18号F1+F2","pro":"24小时,Wi-Fi,礼品卡,生日餐会","provinceName":"北京市","cityName":"北京市"},{"rownum":6,"storeName":"石园南大街","addressDetail":"通顺路石园西区南侧北京顺义西单商场石园分店一层、二层部分","pro":"24小时,Wi-Fi,店内参观,礼品卡,生日餐会","provinceName":"北京市","cityName":"北京市"},{"rownum":7,"storeName":"北京南站","addressDetail":"北京南站候车大厅B岛201号","pro":"Wi-Fi,礼品卡","provinceName":"北京市","cityName":"北京市"},{"rownum":8,"storeName":"北清路","addressDetail":"北京北清路1号146区","pro":"24小时,Wi-Fi,店内参观,礼品卡","provinceName":"北京市","cityName":"北京市"},{"rownum":9,"storeName":"大红门新世纪肯德基餐厅","addressDetail":"海户屯北京新世纪服装商贸城一层南侧","pro":"Wi-Fi,点唱机,礼品卡","provinceName":"北京市","cityName":"北京市"},{"rownum":10,"storeName":"巴沟","addressDetail":"巴沟路2号北京华联万柳购物中心一层","pro":"Wi-Fi,礼品卡,生日餐会","provinceName":"北京市","cityName":"北京市"}]}
数据爬取成功!

在这里插入图片描述

4.2爬取国家药品监督管理局

需求:爬取国家药品监督管理局中化妆品生产许可信息管理系统服务平台,其中每个企业的详细信息。
网址:http://scxk.nmpa.gov.cn:81/xk/

  • 可以发现这是一个json动态页面
  • 我们随意点击进入一个企业,可以发现网址的区别只是后面id不一样
  • 并且可以看到他所需的参数

在这里插入图片描述
在这里插入图片描述
代码实现:

import requests
import json

if __name__ == '__main__':
    # 指定url,国家药品监督总局化妆品生产许可信息管理服务平台
    url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
    # 进行UA伪装
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
    }
    
    id_list = []        # 存贮id信息(需要定义在循环外,要不然就相当于每次循环都创建一个名为id_list的列表,会报错)

    # 从第一页到第六页信息(也可以是从第n页到第m页)
    # page为动态变量表示的是页码数
    for page in range(1,6):
        page = str(page)
        # 参数处理
        param = {
            'on': 'true',
            'page' : page,			# 页码数
            'pageSize' : '15',		# 一页只有15个企业
            'productName': '',
            'conditionType': '1',	# 从第一个企业开始
            'applyname': '',
            'applysn': ''
        }
        # 获取相应数据
        # 为了获取所有企业的id
        response = requests.post(url=url,data=param,headers=header)
        json_id = response.json()
        # print(json_id)

        # 将id信息存入列表中
        for dic in json_id['list']:
            id_list.append(dic['ID'])
        # print(id_list)
    # 获取企业详细信息
    # 每个企业的化妆品生产许可信息
    url1 = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
    # 遍历列表中的id信息,用post方法抓取数据,打印企业详细信息
    for i in id_list:
        data = {
            'id': i
        }
        page_post = requests.post(url=url1,headers=header,data=data).json()
        print(page_post)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值