我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Javascript动态生成的页面信息爬

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Javascript动态生成的页面信息爬

  最近,笔者在使用Requests模拟浏览器发送Post请求时,发现程序返回的html与浏览器F12观察到的略有不同,经过观察返回的response.text,cookies确认有效,因为我们可以看到返回的登陆信息。然而部分字段的值依然显示为空。

下图是浏览器F12抓包看到的界面:

由于笔者在查看第一个接口请求时,观察浏览器捕获到的Response(html文件)跟页面展示的信息一致,就单纯以为只要用requests库构造这个请求即可。然而实际上第一个表单只是返回了前台页面的框架,很多数据都是通过script、XHR等格式的请求返回数据后,再动态加载到基础框架页面的。

那么直接挑重点,请求下面关键的list.do等xhr信息可以吗?

  此例中是不可以的,整个前台网页的内容填充是分模块的,后台每个js文件或者json返回都只决定了页面的一部分信息,这就导致要完整获得页面的信息就需要模拟多个请求。更关键的是,前端页面的部分信息是结合后台的返回的json文件经过一定规律的运算后,才返回的最终结果。如果不能定位到页面中的值后台的运算函数,我们无法模拟后台服务器行为构造同样的函数。

这种靠多个JavaScript文件渲染后生成的网页,直接用requests库来爬取就显得难度较大。

此时通过查阅资料,发现有两种方法来解决JavaScript动态生成页面信息的爬取:(参考博客:https://www.cnblogs.com/taolusi/p/9282565.html

1.1 用dryscrape库动态抓取页面

  js脚本是通过浏览器来执行并返回信息的,所以,抓取js执行后的页面,一个最直接的方式就是用python模拟浏览器的行为。WebKit 是一个开源的浏览器引擎,python提供了许多库可以调用这个引擎,dryscrape便是其中之一,它调用webkit引擎来处理包含js等的网页!ps:该方法由于其底层操作逻辑(python调用 webkit请求页面,而且等页面加载完,载入js文件,让js执行,将执行后的页面返回),导致实际过程偏慢。

import dryscrape
# 使用dryscrape库 动态抓取页面
def get_url_dynamic(url):
    session_req=dryscrape.Session()
    session_req.visit(url) #请求页面
    response=session_req.body() #网页的文本
    #print(response)
    return response
get_text_line(get_url_dynamic(url)) #将输出一条文本

1.2 使用selenium来完成动态页面的爬取

selenium是一个web测试框架,它允许调用本地的浏览器引擎发送网页请求,所以,它同样可以实现抓取页面的要求。

这也是笔者之前大部分文章中推荐的的框架,所谓“可见即可爬”,只可惜效率较requests后台请求的方式,依旧要慢不少。如果能结合Chrome浏览器的headless模式,静默爬取,则能稍微提升一点效率。开启headless模式代码示例:

from selenium import webdriver
option = webdriver.ChromeOptions()
option.add_argument('headless')
driver = webdriver.Chrome(chrome_options=option)
driver.get(url) #访问网址
page_content=driver.page_source #获取js选然后的页面源码

经过上诉操作后,我们就可以拿到页面最终的源码。

但是实际使用中,selenium还有一个问题,就是“可见方可爬”,有些在源码中明明能看到的页面元素,如果前台显示页面,需要点击才会出现,则我们也要模拟浏览器行为,利用click()方法,点击才能拿到相关节点的数据。如:

假如页面停留在“基础信息”界面,如果想取到“审批信息”tab页的信息,则需要模拟点击“审批信息”,这多少会降低爬取效率。

  此时,建议直接用BeautifulSoup包来解析html文件,再配合万能的正则表达式RE直接取,不到迫不得已尽量不去模拟浏览器点击行为(除非页面源码中没有,需要点击触发js动态返回信息的情况)。

下面是我实际工作中结合源码和bs4(BeautifulSoup),re表达式来爬取特定字段的示例:

whole_text=driver.page_source   #提取加载后的源码
soup=BeautifulSoup(whole_text,"lxml")                  
haf=str(soup.select('script')[6])   #得到haf字段,再进行后续提取
flowHiComments=re.search('.*?flowHiComments\":(.*?),\"flowHiNodeIds.*?',haf,re.S)
applyerId=soup.find(id="afPersonId")['value']   #根据id查找 
applyerName=re.search('.*?applyerName\":\"(.*?)\".*?',haf,re.S).group(1) #根据re表达式的group方法提取字符串特定字段
flowHiComments=json.loads(flowHiComments.group(1))  #得到页面评论信息  
with open('.\\CommentFlow\\%s_%s.txt'%(bpmDefName,afFormNumber),'w',encoding="utf-8") as txt:   #将flowHiComments保存为本地txt文件,并对文件进行格式化
    json.dump(flowHiComments,txt,ensure_ascii = False,indent=4)

当拿到特定字段后,就需要逐条对信息进行存储,譬如将信息保存同本地excel文件,这时要用到openpyxl文件。

openpyxl文件对excel新格式的支持比较友好,实际使用中依旧有些地方需要注意:

1.openpyxl默认提供返回excel最后一行(列)的索引号:

利用ws.mas_row和  ws.max_column 两个原生方法即可,但是倘若我们想要读到任意一列的最后一行行号呢?ws.max_row就显得不那么灵活了。

如果要取到A列所有元素到内存,则可以使用的示例代码如下:

name=[]
while True: if sheet.cell(num,1).value ==None: break name.append(sheet.cell(num,1).value) #名称 num+=1

B列的取值,同理可得。

2.我们习惯用ws.append()方法按照行来追加数据到表格中,实测,每次内容追加都是从第二行开始(是否考虑第一行为标题行),倘若我们希望程序执行时动态添加标题行呢?

笔者实测了下:

from openpyxl import load_workbook
wb= load_workbook('test2.xlsx')
#wb.active =1
sheet=wb["Sheet1"]
row = [1 ,2, 3, 4, 5]
sheet.append(row)

wb.save('test2.xlsx')

结果执行完后excel端生成的数据是从第二行开始的:

这显然有时无法满足我们的要求,关于第一行如果要传值就不建议使用原生的append方法了,可行的建议如下:

        
navigation=[]
if ws.cell(1,1).value ==None: navigation=["名称","单号","业务描述","申请者","申请者编号","代码","备注"] for m in range(len(navigation)): ws.cell(1,m+1).value=navigation[m]

上述代码中的navigation列表每个元素当然也能传入爬虫捕获到的字段值(变量),非常灵活!

  爬虫过程中总是遇到这样那样的问题,归纳和总结加上前人积累的经验 就显得尤为重要,避免重复踩坑!

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Javascript动态生成的页面信息爬

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Javascript动态生成的页面信息爬

最近,笔者在使用Requests模拟浏览器发送Post请求时,发现程序返回的html与浏览器F12观察到的略有不同,经过观察返回的response.text,cookies确认有效,因为我们可以看到返回的登陆信息。然而部分字段的值依然显示为
2023-01-30

支持动态页面生成的最强PHP框架

laravel 框架提供动态页面生成能力,通过模型、控制器和视图实现数据处理和页面展示:创建模型以定义数据库表结构。创建控制器以处理请求并返回视图。创建视图以展示数据。定义路由以连接控制器和 url。安装 laravel 并编写代码,运行迁
支持动态页面生成的最强PHP框架
2024-05-23

Python基于Selenium怎么实现动态网页信息的爬取

这篇文章主要介绍“Python基于Selenium怎么实现动态网页信息的爬取”,在日常操作中,相信很多人在Python基于Selenium怎么实现动态网页信息的爬取问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
2023-06-22

Android非XML形式动态生成、调用页面的方法

本文实例讲述了Android非XML形式动态生成、调用页面的方法。分享给大家供大家参考。具体分析如下: 这个问题是这样的:我们不使用XML构建页面,而是使用程序构建新的页面,并在页面中添加各种控件。 一、构建新页面: ① 在src目录中添加
2022-06-06

javascript动态生成css代码的方法是什么

今天小编给大家分享一下javascript动态生成css代码的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。jav
2023-07-04

Wordpress页面静态化与静态文件不生成的解决方法

本文实例讲述了在wordpress中利用cos-html-cache 2.7.3插件来实现Wordpress页面静态化的方法以及静态文件不生成的解决方法,分享给大家供大家参考。具体分析如下: 我们先要下载cos-html-cache 2.7
2022-06-12

如何解决freemarker静态化生成html页面乱码的问题

这篇文章主要介绍了如何解决freemarker静态化生成html页面乱码的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-12

微信小程序开发中如何动态设置当前页面的标题

这篇“微信小程序开发中如何动态设置当前页面的标题”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“微信小程序开发中如何动态设置当前页面的标题”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的
2023-06-26

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录