如何爬取通过ajax加载数据的网站


Posted in Python onAugust 15, 2019

目前很多网站都使用ajax技术动态加载数据,和常规的网站不一样,数据时动态加载的,如果我们使用常规的方法爬取网页,得到的只是一堆html代码,没有任何的数据。

请看下面的代码:

url = 'https://www.toutiao.com/search/?keyword=美女'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}

response = requests.get(url,headers=headers)
print(response.text)

上面的代码是爬取今日头条的一个网页,并打印出get方法返回的文本内容如下图所示,值现在一堆网页代码,并没有相关的头条新闻信息

如何爬取通过ajax加载数据的网站

内容过多,只截取部分内容,有兴趣的朋友可以执行上面的代码看下效果。

对于使用ajax动态加载数据的网页要怎么爬取呢?我们先看下近日头条是如何使用ajax加载数据的。通过chrome的开发者工具来看数据加载过程。

首先打开chrome浏览器,打开开发者工具,点击Network选项,点击XHR选项,然后输入网址:https://www.toutiao.com/search/?keyword=美女  ,点击Preview选项卡,就会看到通过ajax请求返回的数据,Name那一栏就是ajax请求,当鼠标向下滑动时,就会出现多条ajax请求:

如何爬取通过ajax加载数据的网站

通过上图我们知道ajax请求返回的是json数据,我们继续分析ajax请求返回的json数据,点击data展开数据,接着点击0展开数据,发现有个title字段,内容刚好和网页的第一条数据匹配,可知这就是我们要爬取的数据。如下所示:

如何爬取通过ajax加载数据的网站

鼠标向下滚动到网页底部时就会触发一次ajax请求,下面是三次ajax请求:

https://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis
https://www.toutiao.com/search_content/?offset=20&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis
https://www.toutiao.com/search_content/?offset=40&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis

观察每个ajax请求,发现每个ajax请求都有offset,format,keyword,autoload,count,cur_tab,from,pd参数,除了offset参数有变化之外,其他的都不变化。每次ajax请求offset的参数变化规律是0,20,40,60…,可以推测offset是偏移量,count参数是一次ajax请求返回数据的条数。

为了防止爬虫被封,每次请求时要把请求时都要传递请求头信息,请求头信息中包含了浏览器的信息,如果请求没有浏览器信息,就认为是网络爬虫,直接拒绝访问。request header信息如下:

headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0",
"referer": "https://www.toutiao.com/search/?keyword=%E7%BE%8E%E5%A5%B3",
'x-requested-with': 'XMLHttpRequest'
}

完整代码如下:

import requests
from urllib.parse import urlencode

def parse_ajax_web(offset):
  url = 'https://www.toutiao.com/search_content/?'
  #请求头信息
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0",
    "referer": "https://www.toutiao.com/search/",
    'x-requested-with': 'XMLHttpRequest'
  }
  #每个ajax请求要传递的参数
  parm = {
    'offset': offset,
    'format': 'json',
    'keyword': '美女',
    'autoload': 'true',
    'count': 20,
    'cur_tab': 1,
    'from': 'search_tab',
    'pd': 'synthesis'
  }
  #构造ajax请求url
  ajax_url = url + urlencode(parm)
  #调用ajax请求
  response = requests.get(ajax_url, headers=headers)
  #ajax请求返回的是json数据,通过调用json()方法得到json数据
  json = response.json()
  data = json.get('data')
  for item in data:
    if item.get('title') is not None:
      print(item.get('title'))

def main():
  #调用ajax的次数,这里调用5次。
  for offset in (range(0,5)):
    parse_ajax_web(offset*20)

if __name__ == '__main__':
  main()

上面是爬取通过ajax请求加载数据网站的例子,如果想要其他的数据,可以动手自己写,这里只是搭了一个架子,各位可以尝试将数据写入到excel或者数据库中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python用ConfigObj读写配置文件的实现代码
Mar 04 Python
探究数组排序提升Python程序的循环的运行效率的原因
Apr 01 Python
在Python程序中实现分布式进程的教程
Apr 28 Python
不要用强制方法杀掉python线程
Feb 26 Python
[原创]使用豆瓣提供的国内pypi源
Jul 02 Python
Python开发微信公众平台的方法详解【基于weixin-knife】
Jul 08 Python
python去重,一个由dict组成的list的去重示例
Jan 21 Python
python将字符串转变成dict格式的实现
Nov 18 Python
Python 调用有道翻译接口实现翻译
Mar 02 Python
sklearn线性逻辑回归和非线性逻辑回归的实现
Jun 09 Python
Python 如何创建一个线程池
Jul 28 Python
Django crontab定时任务模块操作方法解析
Sep 10 Python
Python K最近邻从原理到实现的方法
Aug 15 #Python
Python数据可视化 pyecharts实现各种统计图表过程详解
Aug 15 #Python
浅谈Python 敏感词过滤的实现
Aug 15 #Python
pycharm创建scrapy项目教程及遇到的坑解析
Aug 15 #Python
通过selenium抓取某东的TT购买记录并分析趋势过程解析
Aug 15 #Python
Python依赖包整体迁移方法详解
Aug 15 #Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 #Python
You might like
虹吸式咖啡壶操作
2021/03/03 冲泡冲煮
php实现从ftp服务器上下载文件树到本地电脑的程序
2009/02/10 PHP
PHP curl_setopt()函数实例代码与参数分析
2011/06/02 PHP
php学习之function的用法
2012/07/14 PHP
UCenter 批量添加用户的php代码
2012/07/17 PHP
PHP调用微博接口实现微博登录的方法示例
2018/09/22 PHP
php给数组赋值的实例方法
2019/09/26 PHP
laravel5.6实现数值转换
2019/10/23 PHP
通用javascript脚本函数库 方便开发
2009/10/13 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
2014/11/23 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
2015/04/14 Javascript
js实现简洁大方的二级下拉菜单效果代码
2015/09/01 Javascript
详解JavaScript中|单竖杠运算符的使用方法
2016/05/23 Javascript
BootStrap栅格系统、表单样式与按钮样式源码解析
2017/01/20 Javascript
js/jq仿window文件夹移动/剪切/复制等操作代码
2017/03/08 Javascript
JS实现课堂随机点名和顺序点名
2017/03/09 Javascript
WebGL学习教程之Three.js学习笔记(第一篇)
2019/04/25 Javascript
js+html实现点名系统功能
2019/11/05 Javascript
JS实现小米轮播图
2020/09/21 Javascript
Python多线程编程(一):threading模块综述
2015/04/05 Python
使用Python进行AES加密和解密的示例代码
2018/02/02 Python
python3+PyQt5实现拖放功能
2018/04/24 Python
python计算两个数的百分比方法
2018/06/29 Python
windows下安装Python虚拟环境virtualenvwrapper-win
2019/06/14 Python
Python Pandas数据中对时间的操作
2019/07/30 Python
python中Lambda表达式详解
2019/11/20 Python
基于Python中isfile函数和isdir函数使用详解
2019/11/29 Python
PyTorch中的Variable变量详解
2020/01/07 Python
基于keras中的回调函数用法说明
2020/06/17 Python
Django模板报TemplateDoesNotExist异常(亲测可行)
2020/12/18 Python
惠普香港官方商店:HP香港
2019/04/30 全球购物
什么是Linux虚拟文件系统VFS
2012/01/31 面试题
Java面试题:Java类的Main方法如果是Private将会怎么样
2016/08/18 面试题
黄金酒广告词
2014/03/21 职场文书
学生安全责任书模板
2014/07/25 职场文书
工商管理专业毕业生自我鉴定2014
2014/10/04 职场文书