【python实现网络爬虫(16)】JSON网易动态新闻爬取(ajax请求爬取信息过程详解,附全部源代码)

1. Ajax 介绍

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。(百度百科),网易新闻的页面就属于这一类,如下,只要一直往下拉,新闻就会一直出现
在这里插入图片描述

2. 爬取逻辑

【找到新闻资讯所在位置】 -> 【确定资源的url】 -> 【获取json数据】 -> 【按需求获取数据并存入数据库或者保存本地】

针对爬取逻辑封装两个函数:

1) 获取资源url的函数

    def get_url(n):

        n:爬取数据的页数
        return返回值: json数据对应url的列表

2) 获取需求数据并存入数据库

     def get_data(url,dic_h,table):

        url:json数据对应的url
        dic_h:请求头
        table:数据库表格
        return返回值:数据爬取量计数

3. 资源url获取

1) 解析json数据文件

首先解析一下网易新闻的页面,在某一新闻页面(比如这里选择的就是’要闻’界面),右键检查,进行测试,和之前获取headers和cookies的操作步骤类似,寻找json数据接口

操作如下:【右键进入检查界面】-> 【选中菜单栏Network】-> 【点击刷新按钮】-> 【查找右下角中的文件】-> 【找到包含json数据的文件】-> 【下拉左侧原界面】-> 【按规律找到全部包含json数据的文件】

图解如下:(因为找到包含json数据的文件是cm_开头的,所以为了过滤掉其他的信息文件,这里直接就只查看所有包含json数据的文件,可以看出没刷新一次页面就会有一个callback文件出现在Name栏下面)
在这里插入图片描述
2) 确定json文件对应的url

在上面的步骤的基础上,点击Preview左侧的Headers,其中Request URL后面的内容就是json数据对应的url了,对应如下

u1 = https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback
u2 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_02.js?callback=data_callback
u3 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_03.js?callback=data_callback
u4 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_04.js?callback=data_callback
u5 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_05.js?callback=data_callback

这里列举了前五页的url,是不是就像最初爬取网页那样也类似的规律呢,也就是第一页的url是可以写成xxx20200213_01.js?xxx类似的格式呢?可以尝试一下,在浏览器界面输入下面这个网址,看看是否真的有规律可循,如下

https://temp.163.com/special/00804KVA/cm_yaowen20200213_01.js?callback=data_callback

–> 输出结果为:(按照相同的方式,发现其他的网页都可以按照原网址进行打开,也就是说这里的首页的url是不符合之前爬虫的网页的规律的,因此需要单独进行判断)
在这里插入图片描述
3) 封装第一个函数,返回url列表

def get_url(n):
    urllst = []
    url_fixed = 'https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback'
    urllst.append(url_fixed)
    urllst.extend([f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback' for i in range(2,n+1)])
    # for i in range(2,n+1):
    #     urllst.append(f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback')
    return urllst

get_url(5)

–> 输出结果为:(对比可以发现这五条数据和在网页上找的url是一致的,在浏览器界面打开后均有数据返回)

['https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback',
 'https://temp.163.com/special/00804KVA/cm_yaowen20200213_02.js?callback=data_callback',
 'https://temp.163.com/special/00804KVA/cm_yaowen20200213_03.js?callback=data_callback',
 'https://temp.163.com/special/00804KVA/cm_yaowen20200213_04.js?callback=data_callback',
 'https://temp.163.com/special/00804KVA/cm_yaowen20200213_05.js?callback=data_callback']
5. 需求数据的爬取并将数据存入数据库

1) 先配置数据库参数

这里使用mongo数据库作为数据存储,比较简单便捷,总共只需要四行代码就配置好数据库,关于mongo数据库的安装可以查看mongo快速入门

#导入数据库模块
import pymongo  
# 链接上服务器
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
#创建一个数据库
db = myclient['腾讯新闻']
#在该数据库下创建一个'表格'保存数据
table = db['data1']

2) 数据爬取试错

在进行大量数据爬取之前,先测试一下能否进行某一页的信息数据的获取,如果没有问题了再进行下一步操作,这样就可以避免出现问题后再回过头来查找错误,节省时间。

在将数据清洗为json可转化的数据类型过程中,要查找位置索引的问题,在之前的python爬取酷狗音乐中已经介绍过,下面直接给出代码

def get_data(url,dic_h,table):
    count = 0
    ri = requests.get(url,headers = dic_h)
    start = ri.text.index('[')
    end = ri.text.index('])') + 1
    datas = json.loads(ri.text[start:end])
    return datas

urllst = get_url(5)
dic_h = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
get_data(urllst[0],dic_h,table)

–> 输出结果为:(这里以第一个url进行试错,查看是否可以成功的返回请求的数据,只截取其中的一条信息)
在这里插入图片描述
3) 获取需求字段信息

在试错无误后就可以或许需求的字段信息了,其中关于keywords字段信息的获取这里可以讲一下,通过上面的输出图片可以发现,所有的信息都是以键值对的形式存储,其他的字段信息都是为字符串,而keywords字段信息是列表中嵌套着字典,因此要提取出里面的keyname信息,还是需要点技巧的,代码如下

for data in datas:
      dic = {}
      dic['title'] = data['title']
      dic['docurl'] = data['docurl']
      dic['commenturl'] = data['commenturl']
      dic['source'] = data['source']
      dic['time'] = data['time'].split(' ')[0]
      dic['keywords'] = ','.join(x['keyname'] for x in data['keywords'])
      count += 1
      #table.insert_one(dic)
      print(dic)

–> 输出结果为:(时间字段进行空格分隔,只选择年月日即可,其他的字段直接可以选取,keywords字段信息需要先遍历表格然后取出里面的keyname信息,再将信息以逗号的形式组成字符串,这样所有需要的字段信息都获取完毕了,也可以添加一些其他的字段爬取信息,未防止审核不通过,下面只截取部分结果)
HM6Ly9ibG9nLmNzZG4ubmV0L2x5c184Mjg=,size_16,color_FFFFFF,t_70)
4) 获取全部数据并保存在数据库

数据插入数据库的操作就是一条指令table.insert_one(dic),打开上面的注释即可,最后进行url的遍历循环即可,为了防止出错,可以加上try-except进行异常处理

error_lst = []
count = 0
for u in urllst:
    try:
        count += get_data(urllst[0],dic_h,table)
        print(f'成功爬取并存储{count}条数据')
    except :
        print('未能爬取数据网址为:',u)
        error_lst.append(u)
6. 全部代码及运行结果

如果要将结果数据

import pymongo
#import pandas as pd
import json,requests


def get_url(n):
    urllst = []
    url_fixed = 'https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback'
    urllst.append(url_fixed)
    urllst.extend([f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback' for i in range(2,n+1)])
    # for i in range(2,n+1):
    #     urllst.append(f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback')
    return urllst

get_url(5)


def get_data(url,dic_h,table):
    n = 0
    ri = requests.get(url,headers = dic_h)
    start = ri.text.index('[')
    end = ri.text.index('])') + 1
    datas = json.loads(ri.text[start:end])
    #data_lst = []
    for data in datas:
        dic = {}
        dic['title'] = data['title']
        dic['docurl'] = data['docurl']
        dic['commenturl'] = data['commenturl']
        dic['source'] = data['source']
        dic['time'] = data['time'].split(' ')[0]
        dic['keywords'] = ','.join(x['keyname'] for x in data['keywords'])
        table.insert_one(dic)
        n += 1
        #print(dic)
        #data_lst.append(dic)
    return n

if __name__ == '__main__':
    
    myclient = pymongo.MongoClient("mongodb://localhost:27017/")
    db = myclient['网易新闻']
    table = db['data1']

    urllst = get_url(5)
    dic_h = {'user-agent': 'Mozilla/5.0'}
    
    
    error_lst = []
    count = 0
    for u in urllst:
        try:
            count += get_data(urllst[0],dic_h,table)
            print(f'成功爬取并存储{count}条数据')
        except :
            print('未能爬取数据网址为:',u)
            error_lst.append(u)

–> 输出结果为:
在这里插入图片描述
生成桌面的文件如下:(截取部分)
在这里插入图片描述

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lys_828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值