Python爬虫:抓取js生成的数据

article/2025/10/11 2:28:42

之前的NLP课程作业要求爬取一些科技新闻来训练语言模型,本文就简单来说一说用Python来爬取新闻的过程。虽然以前写过简单的爬虫,但是没有处理过浏览器动态加载数据的情况,这次碰到了就记录一下。

这次爬取的新闻来源是 新浪科技滚动新闻,打开之后网页长这样:
在这里插入图片描述
该网页中包含了50条新闻,我们希望拿到上图中的新闻链接,然后发送request请求来得到新闻内容。但是查看该网页的源码后发现,这些新闻的链接并不在其中,所以猜测该网页是通过js动态加载得到数据,然后再放入页面。

于是打开浏览器调试工具观察,重新刷新一下界面,可以看到这时浏览器发出了一个请求,请求的url中包含了一些页面的信息,比如页码,该页的新闻数:
在这里插入图片描述
点击Response,查看得到的响应如下,尤其注意图中的框出来的部分包含url,title等信息,其中 ‘\u’开头的字符串就基本表明是跟unicode编码相关的,猜测这些是新闻相关的信息:在这里插入图片描述
得到的响应比较长,这是结尾,这与后面解析这个json文件有关:
在这里插入图片描述
然后尝试打开其中一个url,发现的确就是一个新闻链接。于是使用python的json库对该响应进行解析,因为这个响应的头部和尾部是一些无关紧要的字符串,并且会影响json的解析,所以要将他们去掉:

reply = json.loads(r.text[46:-14])

得到解析结果后,输出一下长度:

print(len(reply['result']['data']))

发现正好是50!也就是之前截图的那个网页的新闻数,到此,可以确定新闻网址的确是这样得到的,我们就可以构造请求头去获取所需的新闻链接了。

观察上面发送请求头的url:

https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid=2515&k=&num=50&page=1&r=0.7908182387933844&callback=jQuery11120751503391487965_1572504701420&_=1572504701424

其中的pageid,lid都是与 "科技"这个主题相关的,不用改变,num = 50是指页面的新闻数,也不用变, page就是第几页,所以翻页时需要改变它,后面的r 以及 jQuery后面的的一串数字可能是与时间戳相关的信息或者随机数,测试后发现改不改得到的结果都是一样,所以不做修改。

所以我们就只需套层循环来改变 page 就可以构造目的url请求了。到此,就可以动手写代码了:

for page_num in range(1, 50):try:url = f'https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid=2515&k=&num=50&page={str(page_num)}&r=0.5' \      f'&callback=jQuery111206769814687743869_1572427017317&_=1572427017314'kv = {'user-agent': 'Mozilla/5.0'}r = requests.get(url, headers=kv)# 解析 json文件reply = json.loads(r.text[46:-14])# print(len(reply['result']['data']))# 处理该页的50条新闻for i in range(0, 50):news_info = [reply['result']['data'][i]['title'], reply['result']['data'][i]['url']]succeed = get_one_news(news_info, news_num)# 成功保存才算数if succeed:news_num += 1news_title_url.append(news_info)if news_num > 1000:breakexcept:print('Something wrong! Ignore it and continue crawl...')continue

 
接下来就是对网页新闻内容进行提取,也就是上面的 get_one_news()函数的实现。
点开一个新闻链接,观察新闻网页源码可以看到:
在这里插入图片描述

新闻内容在 <div class="article" id="artibody" data-sudaclick="blk_content">标签中,利用soup.select('.article'),选出就可以找出原文内容了。
这里的用到了BeautifulSoup库中的select()函数,该函数可以用来查找经BeautifulSoup解析后的网页中的一些内容,比如某个标签,class,或者id,函数返回一个包含搜索结果的list. 该函数的一般用法有:

(1)直接通过标签名查找

print(soup.select('a'))
# [<a href="http://tech.sina.com.cn/" data-sudaclick="nav_tech_p">科技</a>...]

(2)通过类名查找, class名前加 .

print(soup.select('.footer'))
# [<div class="footer">...]

(3)通过 id 名查找,id名前加

print(soup.select('#search_type'))
# [<select id="search_type" name="c" style="visibility: hidden;">...]

(4)组合查找,即查找包含搜索的id,class,标签的组合的结果,关键字用逗号隔开如a标签中 class 为 ico-nav-gotop

print(soup.select('a .ico-nav-gotop'))
# [[<i class="ico-nav-gotop"></i>]]

(5)子标签查找

print(soup.select('tr > td'))
# [<td class="order">序号</td>, <td class="title">关键词</td>...]

(6)属性查找,中间不能加空格,否则匹配不到

print(soup.select('a[href="https://www.aizhan.com/"]'))
# [<a href="https://www.aizhan.com/"><img alt="爱站网" src=...]

 
 
通过上面的操作我们就得到了新闻内容了,有个别的网页在该标签的内部还放有其他内容,比如:在这里插入图片描述在这里插入图片描述
对于第一张图的情况,因为该网站的新闻数足够多,所以直接判断内容开头的几个字符是不是中文,不是就直接跳过这条新闻。

对于第二张图的情况,输出新闻内容字符串可以看到,每次新闻结尾都会有 8 个换行符,然后才会出现后面的内容,所以我们直接从该处截断即可。最后按顺序保存新闻标题及内容即可,考虑到爬取的内容是用于训练的,所以保存的都是500字以上的新闻。另外,这只是粗略的处理了一下文本内容,真正用前还需要再做预处理。这部分都在get_one_news()函数中实现,见下:

def get_one_news(news_infor, n):"""接受新闻标题和网址,以及已爬取的网页数,返回是否成功保存:param news_infor: list,[title, url]:return: 成功保存返回True,否则False"""news_url = news_infor[1]kv2 = {'user-agent': 'Mozilla/5.0'}r2 = requests.get(news_url, headers=kv2)r2.raise_for_status()r2.encoding = r2.apparent_encodingsoup = BeautifulSoup(r2.text, "html.parser")# 取出正文article = []for p in soup.select('.article'):article.append(p.text.strip().lstrip())# 合成字符串article_content = ''.join(article)# 去掉结尾的不需要的内容end = article_content.find('\n\n\n\n\n\n')article_content = article_content[:end]# 判断开头是否含有汉字,因为有可能存在style,这种就直接放弃has_chinese = Falsefor char in article_content[:10]:if '\u4e00' <= char <= '\u9fff':has_chinese = Truebreak# 保证新闻长于500字if has_chinese and len(article_content) > 500:print('[', n, '/ 1000 ] ', news_infor)# 保存新闻filename = str(n) + '.txt'cur_path = os.getcwd()file_path = cur_path + '\\' + filenamewith open(file_path, 'w', encoding='utf-8') as f:f.write(news_infor[0] + '\n')f.write(article_content)return Truereturn False

到此,新闻爬取就完成了,以下是运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

有些新闻网站翻页需要点击 “加载更多” 来加载更多新闻,其实原理和上面也是一样的,在点击的同时会发送一个类似的请求,得到响应内容后,在加载到界面中。当然,像这种还可以用 selenium 库模拟点击动作完成,也比较简单灵活,但是使用该库还需要下载合适的浏览器驱动,而且相对来说速度较慢,尤其是爬取的网页比较多时就可能会比较耗时,具体还得根据实际情况来选择。


http://chatgpt.dhexx.cn/article/oaswltLB.shtml

相关文章

js爬虫

互联网 Web 就是一个巨大无比的数据库&#xff0c;但是这个数据库没有一个像 SQL 语言可以直接获取里面的数据&#xff0c;因为更多时候 Web 是供肉眼阅读和操作的。如果要让机器在 Web 取得数据&#xff0c;那往往就是我们所说的“爬虫”了。现在项目需要&#xff0c;所以研究…

爬虫JS逆向思路 --(几千块钱都学不到的思路)

网络上几千块都学不到的JS逆向思路这里全都有&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb; 本系列持续更新中&#xff0c;三连关注不迷路&#x1f44c;&#x1f3fb; 干货满满不看后悔&#x1f44d;&#x1f44d;&#x1f44d; &…

手把手操作JS逆向爬虫入门(一)

本文爬取的网站如下&#xff08;可以找解密工具解码&#xff09; aHR0cHM6Ly9uZXdyYW5rLmNuLw 爬取的内容为网站的资讯情报版块的新闻资讯 鼠标点击翻页&#xff0c;在开发者工具中查看请求包&#xff0c;很容看出请求地址和参数&#xff0c; 其中post请求的参数如图&#x…

JS实现图片爬虫

最近在在学node.JS&#xff0c;尝试着跟着网上的教程学着写一个JS爬虫,来爬取网上的图片文件&#xff0c;在此记录过程 获取网站的html结构 首先我们引入node.js的http核心模块&#xff0c;初始化并将目标网站地址作为url参数&#xff0c;接受一个回调函数&#xff0c;在这个…

从零开始学JS爬虫,轻松抓取网页数据!

随着互联网的发展&#xff0c;网页已经成为人们获取信息的重要途径之一。而如何高效地获取所需信息&#xff0c;就成为了很多人关注的问题。本文将介绍JS爬虫入门&#xff0c;帮助读者从零开始抓取网页数据。 一、概述 在介绍JS爬虫之前&#xff0c;我们先来了解一下爬虫的基…

爬虫之JS的解析

JS的解析 学习目标&#xff1a; 了解 定位js的方法了解 添加断点观察js的执行过程的方法应用 js2py获取js的方法 1 确定js的位置 对于前面人人网的案例&#xff0c;我们知道了url地址中有部分参数&#xff0c;但是参数是如何生成的呢&#xff1f; 毫无疑问&#xff0c;参数肯…

JavaScript爬取网页并分析

JavaScript爬取网页并分析 任务分析 爬取三个网站下的新闻数据&#xff0c;这里选择网易新闻网&#xff08;https&#xff1a;//news.163.com/&#xff09;&#xff1b;提取每条新闻的如下字段&#xff1a;标题&#xff0c;内容&#xff0c;发表日期&#xff0c;网址&#xf…

js - 爬虫的实现

爬虫的原理 爬虫&#xff0c;就是一个自动爬取网页上展示的信息的工具。我们要写一款爬虫&#xff0c;就要满足下面的条件&#xff1a; 网络的请求。首先我们要进行网络请求&#xff0c;让目标给我们返回信息&#xff08;常用的模块有http、http2、https、request、axios、pu…

Node.js实现简单爬虫 讲解

一、什么是爬虫 网络爬虫(又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者)&#xff0c;是一种按照一定规则&#xff0c;自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕…

爬虫攻略(一)

互联网 Web 就是一个巨大无比的数据库&#xff0c;但是这个数据库没有一个像 SQL 语言可以直接获取里面的数据&#xff0c;因为更多时候 Web 是供肉眼阅读和操作的。如果要让机器在 Web 取得数据&#xff0c;那往往就是我们所说的“爬虫”了。现在项目需要&#xff0c;所以研究…

javascript爬虫

用js爬虫&#xff0c;使用到nodejs 例子中爬取的是中国新闻网时政频道的最新10条新闻的title和链接 事先准备&#xff1a; 1、先去node官网下载安装一下 2、推荐vs code&#xff0c;需要通过终端下载插件&#xff0c;不想的话用cmd小黑框做终端&#xff0c;记事本写代码也行…

用js写个爬虫

如何用js完成爬虫项目 前言一、node.js的安装二、mysql的安装三、确定爬取网页四、查看分析网页源码五、开始写爬虫npmNode调用mysql定义要访问的网站定义新闻页面里具体的元素的读取方式定义哪些url可以作为新闻页面构造一个模仿浏览器的request读取种子页面解析出种子页面里所…

Docker—容器数据卷

目录 1.什么是容器数据卷 2.数据卷的使用 3.实战MySQL同步数据 4.卷 常用命令 5.匿名挂载与具名挂载 5.1 匿名挂载 5.2 具名挂载 6.数据卷容器 1.什么是容器数据卷 Docker将运用与运行的环境打包形成容器运行&#xff0c; Docker容器产生的数据&#xff0c;如果不通过d…

docker删除已停止的容器

一、docker删除已停止的容器 1、根据容器的状态&#xff0c;删除Exited状态的容器 先停止容器、再删除镜像中的容器、最后删除none的镜像。执行命令如下&#xff1a; docker stop $(docker ps -a | grep "Exited" | awk {print $1 }) #停止容器 docker rm $(docke…

Docker与容器的区别

容器 虚拟机和容器结构主要区别在于中间两层&#xff0c;虚拟机自带了操作系统&#xff0c;这个操作系统可以和宿主机一样&#xff0c;也可以不一样&#xff0c;而容器是和宿主机共享一个操作系统。我们知道&#xff0c;操作系统的内容是很多的&#xff0c;就像我们自己电脑上的…

docker 删除 容器/镜像 方法

docker的删除有两种&#xff0c;一个是rm 删除容器&#xff0c;一个是rmi删除镜像 想要删除运行过的images(镜像) 必须首先删除它的container(容器) 首先查看并找到要删除的镜像 docker images 这里我们要删除hello-world镜像 使用rmi 加 镜像id docker rmi fce289e99eb9 报…

docker多容器操作与强制删除容器的方法步骤

简介&#xff1a; 这是一篇有关【doker的多容器操作和强制删除容器的方法】的文章&#xff0c;用最精简的语言去表达给前端读者们。 1、创建多个容器 在WIndows环境下我们来作这个&#xff0c;先打开三个PowerShell窗口&#xff0c;然后在每个窗口中输入创建容器的命令&#…

Docker删除镜像和容器

一、删除容器 首先需要停止所有的容器&#xff08;只停止单个时把后面的变量改为image id即可&#xff09; docker stop $(docker ps -a -q) 删除所有的容器&#xff08;只删除单个时把后面的变量改为image id即可&#xff09; docker rm $(docker ps -a -q) 二、删除镜像…

如何删除docker镜像与容器

目录 删除示例&#xff1a; 1.查看docker中要删除的镜像 2.删除镜像&#xff0c;使用命令“docker rmi image id” 3.查看docker中正在运行的容器 4.停止容器 5.删除容器 6.查看容器 7.删除镜像 8.最后查看所有镜像 删除示例&#xff1a; 1.查看docker中要删除的镜像 …

docker删除容器日志

废话不多数,看步骤 查看容器日志命令 docker logs -f 容器id 1.进入docker容器目录 cd /var/lib/docker/containers/ 2.查看容器的id&#xff0c;获取容器id&#xff0c;容器id就是容器目录名字 docker ps -a 3.进入容器&#xff0c;删除以.log结尾的文件就是日志文件了&a…