Python爬虫:头条小姐姐们都来给你拜年啦!

2024-04-17 07:08

本文主要是介绍Python爬虫:头条小姐姐们都来给你拜年啦!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

觉得上面的小姐姐漂亮的,可以举个爪子。

今天就来教大家来爬取头条上的美女。

但是,不要着急,在学爬虫之前,大家需要先学会分析Ajax请求。

前言

有时候我们会用requests抓取页面的时候,得到的结果可能和浏览器中看到的不一样:在浏览器中可以看到正常显示的页面数据,但是使用requests得到的结果并没有。这是因为requests获取的是原始的HTML文档,而浏览器中的页面则是经过javascript处理数据后生成的结果,这些数据的来源有多种,可能通过Ajax加载的,可能是包含在HTML文档当中,也有可能是经过javascript特定算法计算后生成的。

对于第一种情况:Ajax加载数据是一种异步加载方式,原始的农业面最初是不会包含这些数据的,原始页面加载完成之后,会再向服务器请求某个接口的数据,然后数据就会被处理从而呈现到网页上,这就是一个Ajax请求。

按照目前web的发展形式,这种页面会越来越多。网页的原始HTML中不会包含任何的数据,数据是通过Ajax统一加载后呈现出来的,这样在web开发上可以做到前后分离,而且降低了服务器直接渲染页面带来的压力。

因此,直接利用requests来获取原始HTML,是无法获取到有效的数据的,这时需要分析网页后台向接口发送的Ajax请求,如果可以用requests来模拟Ajax请求,那么就可以正常抓取数据了。

什么是Ajax

Ajax是异步的javascript和xml。它不是一门编程语言,而是利用javascript保证页面不被刷新,URL不变的情况下与服务器交换数据并更新部分网页的技术。

对于传统的网页来说,要想更新数据就必须刷新整个页面,但是有了Ajax之后,便可以在页面不全部刷新的情况下更新内容。在这个过程中实际上是在后台与服务器进行了数据的交换,获取到数据之后,再利用javascript改变网页,这样页面就会刷新了。

Ajax分析方法

这里以微博为例,我们知道拖动刷新的内容由Ajax加载,而且页面的URL没有任何变化,那么应该去哪里查看这些Ajax请求呢?

查看请求

这里还需要借助浏览器的开发者工具,下面以Chrome浏览器为例子进行简单的介绍。

首先,打开微博的首页随便点击任意一条微博,随后在页面中点击鼠标右键,从弹出的快捷键菜单中选择“检查”选项,此时就会弹出开发者工具,如下图所示:

此时在element选项卡中便会观察到网页的源代码。不过这个不是我们需要寻找的内容,切换到network选项卡,随后重新刷新页面,可以发现这里多出了不少的条目,如下图所示:

这里是页面加载过程中浏览器与服务器之间发送请求和接收响应的所有内容。

Ajax其实是特殊的请求类型,它叫做xhr。在下面的图片中,我们可以看到以big为开头的请求,其类型type为xhr,其实这个就是Ajax请求。

鼠标点击该请求的时候,右侧可以看到该请求的Request Headers、URL和Response Headers等信息。其中Request Headers中有个信息为x-requested-with: XMLHttpRequest,这个就是标记此请求就是Ajax请求。如下图所示:

随后点击一下preview,即可看到响应内容,它是json格式的数据,这里的Chrome为我们自动做了解析,点击内容即可展开和收起相应的内容。如下图所示:

由于里面的内容较多,我将它复制下来,比较容易观察。

从上面的图片可以观察到,返回的内容其实是评论者的昵称、评论内容、评论时间以及点赞数。

另外,我们也可以切换到该页面URL的请求,查看它的Response是什么,如下图所示:

经过观察,其实很容易发现,这里的代码非常简单,除了简单的HTML代码之外,其他的都是javascript。所以说,我们看到的微博页面的数据并不是原始的页面返回的,而是后来执行javascript后,再次向后台发送的Ajax请求,浏览器拿到数据之后做进一步的渲染。

过滤请求

接下来利用浏览器中的开发者工具进行筛选,可以将Ajax请求全部筛选出来。在请求的上方有一层筛选栏,直接点击XHR,此时在下方显示的所有请求便都是Ajax请求了,如下图所示:

接下来,不断的滑动页面,可以看到页面底部有一条条新的微博评论被刷出,而开发者工具下方也会有一个个Ajax请求出现,这样我们就可以捕捉到所有的Ajax请求了。如下图所示:

至此,我们基本上可以分析出Ajax请求的一些详细信息了,接下来只需要用程序模拟这些Ajax请求,就可以轻松的获取到我们需要的信息了。

实战

分析Ajax爬取今日头条小姐姐

准备工作

在项目开始之前,请确保已经安装好requests库,如果没有安装,请参考下面的安装方法:

pip install requests

抓取分析

在抓取之前,首先要分析抓取的逻辑。打开今日头条的首页:https://www.toutiao.com/

在左上角有一个搜索接口,这里尝试抓取美女图片,所以输入“美女”二字搜索一下,如下图所示:

这时打开开发者工具并刷新整个页面,你会发现在network选项卡中会出现大量的数据请求信息。点击第一个请求,并点击response选项,搜索“写真”,遗憾的事情发生了,里面没有出现任何的关于写真的字眼。

因此,可以初步判断这些内容是由Ajax加载的,然后利用javascript渲染出来,接下来切换到XHR选项卡,查看有没有Ajax请求,如下图所示:

不出所料,这里果然出现了一些比较常规的Ajax请求,看看它的结果是否包含了页面中的相关数据。

点击data字段展开,发现这里许多条数据。点击第一条展开,发现有article_url字段和title字段与网页内容基本符合。

切换回headers选项卡,观察URL和headers信息,如下图所示:

可以看到这是一个get请求,请求的URL参数有:aidapp_nameoffsetformatkeywordautoloadcounten_qccur_tabfrompdtimestamp_signature

继续下滑网页,你会发现在XHR选项卡中会出现越来越多的符合条件的Ajax请求。

如下所示:

https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis&timestamp=1612428382721&_signature=_02B4Z6wo00f015gKQTwAAIDAKPut9b7JdoeYL0WAAIYhGfqDyZWOUeA.JwSONVd37BCTuUrJwE1gIOy3vdsi5j5EDUTmLQeASGQij2uMyxRGe3E8Peoo2hzHzz5RwATyAVC1zu18zMfLZ5S3ahttps://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=20&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis&timestamp=1612429526639&_signature=_02B4Z6wo00d01lR4bAgAAIDB5ImAw3OJbZpUXWiAAPUUQO2SS7CFcMRjXUZZEIHjqP2egcZBSpXYmI6hWj.iKGkzEg0JBWChgQPoggOPf63cZGszmYGGuZdc1vbIO9gVPQmgwTOGo6qCxbjK94https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=40&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis&timestamp=1612429531243&_signature=_02B4Z6wo00d01GfNiKwAAIDD1zxkZOf0K2hn6IwAAHnwQO2SS7CFcMRjXUZZEIHjqP2egcZBSpXYmI6hWj.iKGkzEg0JBWChgQPoggOPf63cZGszmYGGuZdc1vbIO9gVPQmgwTOGo6qCxbjKddhttps://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=60&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis&timestamp=1612429538566&_signature=_02B4Z6wo00d01tH81gwAAIDBYQ06xI8rJLrR2dKAANRxQO2SS7CFcMRjXUZZEIHjqP2egcZBSpXYmI6hWj.iKGkzEg0JBWChgQPoggOPf63cZGszmYGGuZdc1vbIO9gVPQmgwTOGo6qCxbjK95

通过观察,可以发现变化的内容有offset,timestamp_signature    。

timestamp指的是时间戳,而_signature指的是签名认证。我自己也看了很多的教程,大多数关于这个 _signature的破解其实是js的逆向。本来我也想要写用js逆向来破解这个 _signature,但是想到大家对于js逆向的方法可能不熟悉,毕竟我还没有写过该类文章,因此就不用这个方法了。经过测试发现不添加 _signature这个参数,对于获取json响应并无影响。

并且通过分析该Ajax请求可以发现,里面有image_list字段,如下图所示:

将这三个URL地址依次复制到浏览器之后可以发现,正是图片的URL地址,但是需要注意的是这个并不是高清大图的URL地址。

那问题就出现了,如何获取高清大图的URL地址呢?

如上图所示,可以依次点击URL地址,点击进去之后就会发现里面的都是高清大图的美女图片了。如下图所示:

那接下来就可以来看看json数据的URL和高清大图的URL存在着什么样的区别。

json数据内的URL
http://p1-tt.byteimg.com/list/190x124/pgc-image/183b0a981cf04498958beb194613fe43高清大图的URL
https://p6-tt.byteimg.com/origin/pgc-image/183b0a981cf04498958beb194613fe43?from=pc

通过观察上面的两个URL,其实区别也不是很大,只需要替换一些字符就可以了。

功能需求与实现

获取json数据

获取json数据倒不是特别难,主要是构造URL参数,具体代码如下所示:

def get_page(offset):global headersheaders = {'cookie': 'tt_webid=6925326312953529869; s_v_web_id=verify_kkqm44un_jaeWrYZ1_CnOS_4Xuz_BNoi_lE3QmTQ37uHC; csrftoken=280e107c397cea753911229202dc0c3d; ttcid=45904355bfa4470f9543c9cdeb94869f30; tt_webid=6925326312953529869; csrftoken=280e107c397cea753911229202dc0c3d; __ac_signature=_02B4Z6wo00f01Coh3wgAAIDDmtAzwcHMKowqBduAAGqaWRSmr26jOpvMaDLR3MsdEfPZTRN9mxTbUMgGifTuVJdj6FgWrIu6yKXVS3Dsp.wz3Pxl9vgfeguqCWDdZ4ocFVxb4JgkNBJTefPR41; __tasessionId=pyia55cn11612433914121; MONITOR_WEB_ID=2264d055-a390-4e4b-9b1f-4a3e2a6ac47c; tt_scid=pcBhM4miMb3tReqLN21gkwPxqHE92TFulL0hVtP4mdhm0UL1X0v0T1r158U8hVOua37f','referer': 'https://www.toutiao.com/search/?keyword=%E7%BE%8E%E5%A5%B3','user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36','x-requested-with': 'XMLHttpRequest'}params = {'aid':'24','app_name':'web_search','offset':offset,'format':'json','keyword':'美女','autoload':'true','count':'20','en_qc':'1','cur_tab':'1','from':'search_tab','pd':'synthesis','timestamp':int(time.time())}url = 'https://www.toutiao.com/api/search/content/?'try:response = requests.get(url, headers=headers, params=params)response.content.decode('utf-8')if response.status_code == 200:return response.json()except requests.ConnectionError as e:print('连接失败', e)

获取图片地址

经过上面的分析发现,json内部的图片链接并不是高清大图,所以在这里需要获取高清大图时需要做简单的字符串替换。

具体代码如下所示:

def get_info(json):new_img_lists = []image_lists = jsonpath.jsonpath(json, '$.data[*].image_list..url')for image_list in image_lists:new_img_list = image_list.replace('p1', 'p6').replace('p3', 'p6').replace('list','origin').replace('/190x124', '')new_img_lists.append(new_img_list)return new_img_lists

保存图片

保存图片的时候只需要向上面获取到的图片地址依次发送请求即可。具体代码如下所示:

def save_img(new_image_lists):global namefor image in new_image_lists:print('-------正在获取第{}张----------'.format(name))data = requests.get(image, headers=headers).contentwith open(f'../image/{name}.jpg', 'wb') as f:f.write(data)name += 1

结果展示

关于翻页

其实翻页问题相当的好解决,通过对上面Ajax的接口就可以发现offset其实就是实现翻页效果的参数,每一次都是20的倍数,因此只需要传递offset的偏移量即可。

具体代码如下所示:

def main(offset):json = get_page(offset)# print(type(json))new_image_lists = get_info(json)save_img(new_image_lists)if __name__ == '__main__':pool = Pool()groups = [i * 20 for i in range(4)] # 0 20 40pool.map(main, groups) # 传递偏移量pool.close()pool.join()

最后结果

通过上图以及代码可以知道,我只传递了3个偏移量,就获取到了229张的美女图片。

以上就是今天分享的所有内容了。

本篇文章告诉了大家:什么是Ajax?、如何查看与过滤Ajax请求。希望各位小伙伴以后遇到类似的问题可以举一反三,加强练习。

最后

来自啃书君警告

美女虽好,切莫贪杯,要是自己的ip被封了就得不偿失了。

啃书君说

没有一件事是可以一蹴而就的,哪有什么三天速成,七天速成,没有坚持何来成功!生活如此,学习亦是如此!

文章的每一个字,都是我用心敲出来的,只希望对得起每一位关注我的人。

在文章末尾点个【赞】与【在看】,让我知道,你们也在为自己的学习拼搏和努力着。

扫一扫下面的二维码,加我一起交流哦(拉你加Python交流群)~

“扫一扫加我”

这篇关于Python爬虫:头条小姐姐们都来给你拜年啦!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/911120

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',

Python3 BeautifulSoup爬虫 POJ自动提交

POJ 提交代码采用Base64加密方式 import http.cookiejarimport loggingimport urllib.parseimport urllib.requestimport base64from bs4 import BeautifulSoupfrom submitcode import SubmitCodeclass SubmitPoj():de

Python QT实现A-star寻路算法

目录 1、界面使用方法 2、注意事项 3、补充说明 用Qt5搭建一个图形化测试寻路算法的测试环境。 1、界面使用方法 设定起点: 鼠标左键双击,设定红色的起点。左键双击设定起点,用红色标记。 设定终点: 鼠标右键双击,设定蓝色的终点。右键双击设定终点,用蓝色标记。 设置障碍点: 鼠标左键或者右键按着不放,拖动可以设置黑色的障碍点。按住左键或右键并拖动,设置一系列黑色障碍点

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目