动态网页抓取(Ajax理论1.Ajax提取AjaxAjaxAjax分析 )
优采云 发布时间: 2021-11-19 01:14动态网页抓取(Ajax理论1.Ajax提取AjaxAjaxAjax分析
)
上面提到的爬虫都是建立在静态网页的基础上的。首先通过请求网站url获取网页源码。之后,从源代码中提取信息并存储。本文将重点介绍动态网页数据采集,先介绍Ajax相关理论,然后在实战中爬取Flush的动态网页,获取个股信息。
内容
一、Ajax 理论
1.Ajax 简介
2.ajax分析
3.Ajax 提取
二、网络分析
1.网页概览
2.Ajax 歧视
3.Ajax 提取
三、爬虫实战
1.网页访问
2.信息抽取
3.保存数据
4.循环结构
一、Ajax 理论
1.Ajax 简介
Ajax 代表“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),它指的是一种 Web 开发技术,可以创建交互式、快速和动态的 Web 应用程序,并且可以在不重新加载整个网页的情况下更新某些网页。通过在后台与服务器交换少量数据,Ajax 可以使网页异步更新。这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。
2.ajax分析
微博网站是一个带有Ajax的动态网页,易于识别。首先打开Dectools工具(调整到XHR专栏)和中南财经政法大学官方微博网站(),这里选择的是移动端微博,然后选择清除所有内容.
接下来,滚动滚轮以下拉页面,直到清空的 XHR 列中出现新项目。点击此项,选择预览栏,发现这里对应的内容是页面上新出现的微博,上面的网页链接但是没有变化。此时,我们可以确定这是一个Ajax请求后的网页。
3.Ajax 提取
还是选择同一个入口进入Headers进一步查看信息,可以发现这是一个GET类型的请求,请求url为:,即请求参数有4个:type、value、containerid、since_id,然后翻页发现,除了since_id发生了变化,其余的都保持不变。这里我们可以看到since_id是翻页方法。
接下来观察since_id,发现上下请求之间的since_id没有明显的规律。进一步搜索发现下一页的since_id在上一页的响应中的cardListInfo中,因此可以建立循环连接,进一步将动态URL添加到爬虫中。
发起请求获取响应后,进一步分析发现响应格式是json,所以进一步处理json就可以得到最终的数据了!
二、网络分析
1.网页概览
有了上面的分析,我们就用flush网页采集的数据,通过实战来验证一下。首先打开网页:如下图:
再按F12键打开Devtools后端源代码,将鼠标放在第一项上,点击右键,查看源代码中的位置。
2.Ajax 歧视
接下来,我们点击网页底部的下一页,发现网页url没有任何变化!至此,基本可以确定该网页属于Ajax动态网页。
进一步,我们清除了网络中的所有内容,继续点击下一页到第五页,发现连续弹出了三个同名的消息。请求的URL和请求头的具体内容可以通过General一栏获取。
于是,我们复制了请求的url,在浏览器中打开,结果响应内容是标准化的表格数据,正是我们想要的。
3.Ajax 提取
然后我们也打开源码,发现是一个html文档,说明响应内容是网页形式,和上面微博响应的json格式不同,所以可以在后面的网页分析的形式。
三、爬虫实战
1.网页访问
在第一部分的理论介绍和第二部分的网页分析之后,我们就可以开始编写爬虫代码了。首先,导入库并定义请求头。需要注意的一点是,这里的请求头除了User-Agent之外,还需要host、Referer和X-Requested-With参数,这应该和静态网页爬取区别开来。
# 导入库
import time
import json
import random
import requests
import pandas as pd
from bs4 import BeautifulSoup
headers = {
'host':'q.10jqka.com.cn',
'Referer':'http://q.10jqka.com.cn/',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3554.0 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}
url = 'http://q.10jqka.com.cn/index/index/board/all/field/zdf/order/desc/page/%s/ajax/1/' % page_id
res = requests.get(url,headers=headers)
res.encoding = 'GBK'
2.信息抽取
之后就是上面分析库的内容了,这里就更容易理解BaetifulSoup库了。首先将上面的html转换成一个BeautifulSoup对象,然后通过对象的select选择器选择响应tr标签中的数据,进一步分析每个tr标签的内容,得到如下对应的信息。
# 获取单页数据
def get_html(page_id):
headers = {
'host':'q.10jqka.com.cn',
'Referer':'http://q.10jqka.com.cn/',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3554.0 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}
url = 'http://q.10jqka.com.cn/index/index/board/all/field/zdf/order/desc/page/%s/ajax/1/' % page_id
res = requests.get(url,headers=headers)
res.encoding = 'GBK'
soup = BeautifulSoup(res.text,'lxml')
tr_list = soup.select('tbody tr')
# print(tr_list)
stocks = []
for each_tr in tr_list:
td_list = each_tr.select('td')
data = {
'股票代码':td_list[1].text,
'股票简称':td_list[2].text,
'股票链接':each_tr.a['href'],
'现价':td_list[3].text,
'涨幅':td_list[4].text,
'涨跌':td_list[5].text,
'涨速':td_list[6].text,
'换手':td_list[7].text,
'量比':td_list[8].text,
'振幅':td_list[9].text,
'成交额':td_list[10].text,
'流通股':td_list[11].text,
'流通市值':td_list[12].text,
'市盈率':td_list[13].text,
}
stocks.append(data)
return stocks
3.保存数据
定义 write2excel 函数将数据保存到stocks.xlsx 文件中。
# 保存数据
def write2excel(result):
json_result = json.dumps(result)
with open('stocks.json','w') as f:
f.write(json_result)
with open('stocks.json','r') as f:
data = f.read()
data = json.loads(data)
df = pd.DataFrame(data,columns=['股票代码','股票简称','股票链接','现价','涨幅','涨跌','涨速','换手','量比','振幅','成交额', '流通股','流通市值','市盈率'])
df.to_excel('stocks.xlsx',index=False)
4.循环结构
同时考虑到flush的多页结构和反爬虫的存在,也采用字符串拼接和循环结构来遍历多页股票信息。同时,随机库中的randint方法和时间库中的sleep方法在爬行前中断一定时间。
def get_pages(page_n):
stocks_n = []
for page_id in range(1,page_n+1):
page = get_html(page_id)
stocks_n.extend(page)
time.sleep(random.randint(1,10))
return stocks_n
最终爬取结果如下:
至此,Flush动态网页的爬取完成,接下来由这个爬虫总结:首先,我们通过浏览网页结构,翻页,对比XHR栏,对变化的网页进行Ajax判断。如果网页url不变,XHR会刷新内容,基本说明是动态网页,此时我们进一步检查多个页面之间URL请求的异同,找出规律。找到规则后,就可以建立多页请求流程了。之后对单个响应内容进行处理(详细参见响应内容的格式),最后建立整个循环爬虫结构,自动爬取所需信息。
爬虫完整代码可在公众号回复“Flush”获取。下面将进一步讲解和实战浏览器模拟行为。上一篇涉及的基础知识,请参考以下链接:
我知道你在“看”