AI网络爬虫:搜狗图片的时间戳反爬虫应对策略

如何批量爬取下载搜狗图片搜索结果页面的图片?以孙允珠这个关键词的搜索结果为例:

https://pic.sogou.com/pics?query=%E5%AD%99%E5%85%81%E7%8F%A0&mode=2

翻页规律如下:

https://pic.sogou.com/napi/pc/searchList?mode=2&start=384&xml_len=48&query=%E5%AD%99%E5%85%81%E7%8F%A0&channel=pc_pic

https://pic.sogou.com/napi/pc/searchList?mode=2&start=336&xml_len=48&query=%E5%AD%99%E5%85%81%E7%8F%A0&channel=pc_pic

https://pic.sogou.com/napi/pc/searchList?mode=2&start=288&xml_len=48&query=%E5%AD%99%E5%85%81%E7%8F%A0&channel=pc_pic

这三个URL都指向同一个服务,即搜狗图片搜索的API,用于获取孙允珠相关的图片搜索结果。它们之间的规律主要体现在查询参数 `start` 和 `xml_len` 上:

  1. **start** 参数:这个参数控制了搜索结果的起始位置。在第一个URL中,`start` 的值是384,第二个URL中是336,第三个URL中是288。这表明每次请求的搜索结果是从前一次请求的结果之后开始获取的。例如,如果每页显示48张图片(由 `xml_len` 参数决定),那么第一个URL将从第8页开始(384 / 48 = 8),第二个URL从第7页开始(336 / 48 = 7),第三个URL从第6页开始(288 / 48 = 6)。
  2. **xml_len** 参数:这个参数指定了每次请求返回的图片数量,其值为48,意味着每次请求都会返回48张图片。
  3. **query** 参数:这个参数指定了搜索的关键词,这里是“孙允珠”,表示搜索与孙允珠相关的图片。
  4. **channel** 参数:这个参数指定了请求的渠道,这里是 `pc_pic`,表示这是一个针对PC端图片搜索的请求。

总结规律:这三个URL通过调整 `start` 参数的值,实现了分页获取搜索结果的功能。每次请求都是从前一次请求的下一页开始获取图片,每次获取48张图片。这种设计允许用户或应用程序逐步加载更多的搜索结果,而不需要一次性加载所有结果,从而优化了数据加载的效率和用户体验。

返回的是json数据:

{

"status": 0,

"info": "ok",

"data": {

"adPic": [

{

"docId": "e154002750821088-37dc5468319bfb35-9215f4c834c26f0856ee7b118f22b559",

"index": 0,

"mfid": "128a42e5ea3535cd",

"thumbHeight": 1043,

"thumbWidth": 500

},

{

"docId": "abe1eea3ca79fc28-c577ebdcb0f3dbcc-a5f4cbbb2bfe711fad33ce48dce150b3",

"index": 1,

"mfid": "46ff91955836d2f8",

"thumbHeight": 767,

"thumbWidth": 499

},

{

"docId": "c286ca7ecc6f7a79-20248c558009c911-5d0f8afe47cd75de9dcce97d6d0e92d4",

"index": 2,

"mfid": "99a6652c227b8833",

"thumbHeight": 768,

"thumbWidth": 500

}

],

"blackLevel": 5,

"cacheDocNum": 48,

"hasPicsetRes": 0,

"isQcResult": "0",

"is_strong_style": 1,

"items": [

{

"anchor1": "",

"anchor2": [],

"anchor_extend": {},

"author": "http://pic.sogou.com",

"author_name": "",

"author_pageurl": "",

"author_picurl": "",

"author_thumbUrl": "https://i02piccdn.sogoucdn.com/0000000000000000_author",

"author_thumb_mfid": "0000000000000000",

"beauty": 7,

"biaoqing": 0,

"ch_site_name": "搜狐网",

"clarity": 5,

"content_major": "裙子的部分是一个直筒型的规划,简略直接的裙边线条调配上裙子内向缩短的规划,使裙子的风格偏向于简练,内敛的风格。别的延展至膝部的裙尾也遮盖了大部分腿部线条,调配浅褐色的使用,营建出了一种保守,庄雅的感觉。 衣服的外层有一个以腰部为支点,斜向的X型的面料系",

"cutBoardInputSkin": "c24c00231bcf459d|11|1718942349116|99418a699300bedc52a7df9b832a7aa0|http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20200212%2Fab9b05decd8d4b4eb39bb287cf0c14ad.jpeg",

"docId": "abe1eea3ca79fc28-c577ebdcb0f3dbcc-4b0aa372e8378eaa63bf649210d0bfc4",

"docidx": 96,

"gifpic": 0,

"grouppic": 1,

"height": 991,

"https_convert": 0,

"index": 0,

"lastModified": "1581484601",

"like_num": "0",

"link": "http://pic.sogou.com/d?query=%CB%EF%D4%CA%D6%E9&mode=2&mood=0&did=97&dm=0&id=abe1eea3ca79fc28-c577ebdcb0f3dbcc-4b0aa372e8378eaa63bf649210d0bfc4",

"locImageLink": "https://i02piccdn.sogoucdn.com/cf2dc47f12f2d0e9",

"mf_id": "cf2dc47f12f2d0e9",

"mood": "0x80",

"name": "ab9b05decd8d4b4eb39bb287cf0c14ad.jpeg",

"oriPicUrl": "http://5b0988e595225.cdn.sohucs.com/images/20200212/ab9b05decd8d4b4eb39bb287cf0c14ad.jpeg",

"painter_year": "",

"picUrl": "http://5b0988e595225.cdn.sohucs.com/images/20200212/ab9b05decd8d4b4eb39bb287cf0c14ad.jpeg",

"pic_norm_score": 0.998463,

"pic_porn_score": 0.000002,

"pic_sexy_score": 0.001535,

"pic_vulgar_score": 0,

"publish_time": "1581448740",

"publishmodified": "",

"rank": -100.9800033569336,

"size": 118807,

"summarytype": "NormalSummary",

"thumbHeight": 569,

"thumbUrl": "https://i02piccdn.sogoucdn.com/cf2dc47f12f2d0e9",

"thumbWidth": 499,

"title": "孙允珠 浅咖缠叠修身礼裙鉴赏",

"type": ".jpeg",

"url": "https://www.sohu.com/a/372330552_100198733",

"wapLink": "https://pic.sogou.com/pic/download.jsp?v=5&eid=1951&keyword=%E5%AD%99%E5%85%81%E7%8F%A0&index=97&groupIndex=96&xurl=https://i02piccdn.sogoucdn.com/cf2dc47f12f2d0e9&durl=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20200212%2Fab9b05decd8d4b4eb39bb287cf0c14ad.jpeg",

"water_mark_confidence": 0.78199702501297,

"width": 870,

"did": 97,

"scale": 0.8769771528998243,

"imgTag": "",

"bgColor": "#e3ddf6",

"imgDefaultUrl": "/d?query=%E5%AD%99%E5%85%81%E7%8F%A0&forbidqc=&entityid=&preQuery=&rawQuery=&queryList=&st=&channel=pc_pic&mode=2&did=97"

},

图片下载地址在 "picUrl"这个键的值中。

但是写了爬虫程序后,json数据爬取失败。仔细检查请求头,原来是里面加了时间戳:

X-Time4p 是一个自定义的HTTP头部字段,通常用于传递与时间相关的信息。在这个上下文中,它可能被用来传递服务器处理请求的时间戳。不同的 X-Time4p 值表示不同的时间戳,这些时间戳对应于服务器处理不同请求的时刻。

例如,X-Time4p: 1718942347427 和 X-Time4p: 1718945416096 之间的区别在于它们代表了两个不同的时间点:

1718942347427 对应于服务器处理第一个请求的时间。

1718945416096 对应于服务器处理第二个请求的时间。

这两个时间戳之间的差异(大约3068677秒)表明服务器在处理这两个请求之间经过了多长时间。在Python脚本中,X-Time4p 的值应该与请求头中的其他字段一起设置,以模拟真实的浏览器请求。需要在不同的请求中使用不同的时间戳,因为要模拟不同时间点的请求,或者服务器可能期望看到不同的时间戳以正确处理请求。

在Python中生成时间戳,你可以使用内置的time模块中的time()函数。这个函数返回自1970年1月1日00:00:00(UTC)以来的秒数,这是一个常见的时间戳格式。

如果你想要生成类似于X-Time4p中使用的特定时间戳,你可以使用time.time()函数,然后根据需要调整返回的值。例如,如果你想要生成一个与给定时间戳相似的时间戳,你可以添加或减去一定数量的秒数。

'X-Time4p': str(int(time.time() * 1000)) # 生成当前时间的时间戳,单位为毫秒

在ChatGPT中输入提示词:

你是一个Python编程专家,写一个Python脚本,爬取网页图片:

请求网址:

https://pic.sogou.com/napi/pc/searchList?mode=2&start={pagenumer}&xml_len=48&query=%E5%AD%99%E5%85%81%E7%8F%A0&channel=pc_pic

{pagenumer}值从48开始,以48递增,一直到1008结束;

请求方法:

GET

状态代码:

200 OK

远程地址:

61.151.229.174:443

引荐来源网址政策:

no-referrer

请求标头

Accept:

application/json, text/plain, */*

Accept-Encoding:

gzip, deflate, br, zstd

Accept-Language:

zh-CN,zh;q=0.9,en;q=0.8

Connection:

keep-alive

Host:

http://pic.sogou.com

Sec-Ch-Ua:

"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"

Sec-Ch-Ua-Mobile:

?0

Sec-Ch-Ua-Platform:

"Windows"

Sec-Fetch-Dest:

empty

Sec-Fetch-Mode:

cors

Sec-Fetch-Site:

same-origin

User-Agent:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36

X-Time4p:{thistime}

{thistime}是一个时间戳,比如这样:1718945416096,要用str(int(time.time() * 1000)) 来 生成当前时间的时间戳,单位为毫秒;

请求响应是多层嵌套的json数据,输出这个json数据到屏幕上;

将 JSON 字符串解析为一个 Python 字典,首先获取 "data" 键对应的子字典,然后访问子字典中的 "items" 键,"items" 键对应的值是一个列表,获取所有列表中"picUrl"键对应的值 ,这是一个图片url,将url写入Excel表格第1列,Excel表格文件保存到文件夹:"C:\Users\dell\Pictures\孙允珠"

注意:每请求一个网页,随机暂停3-6秒;

每一步都输出信息到屏幕

源代码:

import requests

import json

import time

import random

from openpyxl import Workbook

# 设置请求头部信息

headers = {

"Accept": "application/json, text/plain, */*",

"Accept-Encoding": "gzip, deflate, br, zstd",

"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",

"Connection": "keep-alive",

"Host": "http://pic.sogou.com",

"Sec-Ch-Ua": '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',

"Sec-Ch-Ua-Mobile": "?0",

"Sec-Ch-Ua-Platform": '"Windows"',

"Sec-Fetch-Dest": "empty",

"Sec-Fetch-Mode": "cors",

"Sec-Fetch-Site": "same-origin",

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"

}

# Excel文件保存路径和文件名

excel_file = r"C:\Users\dell\Pictures\孙允珠\pic_urls.xlsx"

# 创建一个新的Excel工作簿

wb = Workbook()

ws = wb.active

ws.title = "Pic URLs"

ws.append(["图片链接"]) # 添加表头

# 定义生成时间戳的函数

def generate_timestamp():

return str(int(time.time() * 1000))

# 主程序逻辑

base_url = "https://pic.sogou.com/napi/pc/searchList"

start_pagenum = 48

end_pagenum = 1008

page_increment = 48

for pagenum in range(start_pagenum, end_pagenum + 1, page_increment):

try:

# 构建请求URL和参数

url = base_url + f"?mode=2&start={pagenum}&xml_len=48&query=%E5%AD%99%E5%85%81%E7%8F%A0&channel=pc_pic"

thistime = generate_timestamp()

headers["X-Time4p"] = thistime

# 发送GET请求

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

response.raise_for_status() # 检查请求是否成功

# 解析JSON响应

data = response.json()

# 输出JSON数据到屏幕上

print(f"获取到的 JSON 数据:\n{json.dumps(data, indent=2, ensure_ascii=False)}")

# 获取图片链接并写入Excel表格

if data and "data" in data and "items" in data["data"]:

items = data["data"]["items"]

for item in items:

pic_url = item.get("picUrl")

if pic_url:

print(f"图片链接:{pic_url}")

ws.append([pic_url]) # 写入Excel表格

else:

print("未找到图片链接")

else:

print("未找到data或items键")

except requests.exceptions.RequestException as e:

print(f"请求失败: {e}")

# 随机暂停3-6秒

pause_time = random.uniform(3, 6)

print(f"随机暂停 {pause_time:.2f} 秒")

time.sleep(pause_time)

print("所有操作完成!")

# 保存Excel文件

wb.save(excel_file)

# 关闭Excel工作簿

wb.close()

获取到图片下载地址,然后用迅雷批量下载,这样下载速度更快:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/32369.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter开发环境搭建和调试

[你的Flutter文件夹路径]\flutter\bin 这样我们的Flutter SDK的环境变量就配置完毕了。接下来在命令提示符窗口中输入命令: flutter doctor 它可以帮助我们检查Flutter环境变量是否设置成功,Android SDK是否下载以及配置好环境变量等等。如果有相关的…

【接口自动化测试】第二节.Requests库和接口对象封装

文章目录 前言一、Requests库 1.1 Requests介绍 1.2 Requests发送请求 1.3 Requests查看响应 1.4 案例1登录接口调试-获取验证码 1.5 案例2登录接口调试-登录 1.6 归纳小结二、接口对象封装 2.1 当前代码待优化问题 2.2 接口对象封装思…

仿饿了么加入购物车旋转控件 - 自带闪转腾挪动画 的按钮

, mWidth - mCircleWidth, mHeight - mCircleWidth); canvas.drawRoundRect(rectF, mHintBgRoundValue, mHintBgRoundValue, mHintPaint); //前景文字 mHintPaint.setColor(mHintFgColor); // 计算Baseline绘制的起点X轴坐标 int baseX (int) (mWidth / 2 - mHintPaint.m…

【面试实战】# 并发编程之线程池配置实战

1.先了解线程池的几个参数含义 corePoolSize (核心线程池大小): 作用: 指定了线程池维护的核心线程数量,即使这些线程处于空闲状态,它们也不会被回收。用途: 核心线程用于处理长期的任务,保持最低的线程数量,以减少线程的创建和…

springboot中,将某个函数的日志单独输出的方法

背景 项目中有个节点健康检查扫描功能,每10秒扫描一次节点。 如果节点挂掉,会输出健康检查失败的日志。 测试环境,虽然配置了多个节点,但并没有都启动,所以在扫描的时候,会不断的出现报错, 对于…

【low-ui-vue】实现原生可扩展动态表格组件

本文字数:3520字 预计阅读时间:20分钟 所谓动态列的表格,就是列数不固定。像广为使用的elementUI的table组件就是表头写死的,这种也叫列数固定的表格。 01 效果 当然,动态性增加了,当然要做出一定“牺牲”。…

【前端vue3】TypeScrip-Class类用法

类型声明 TypeScrip定义Class类 语法: // 定义一个名为 Person 的类 class Person {constructor () {// 构造函数:稍后定义}run () {// 方法:稍后定义} }在TypeScript是不允许直接在constructor 定义变量的 需要在constructor上面先声明 例…

csdn上传源码资源卖钱能买房买车吗?每天最高收入200-500?

csdn上传源码卖钱能买房买车吗,最高收入200-500? 作者收入日榜 不***孩 收益617.32元 程***妍 收益534.56元 s***n 收益323.71元 盈***客 收益315.05元 极***计 收益284.17元

2024-06-23 编译原理实验4——中间代码生成

文章目录 一、实验要求二、实验设计三、实验结果四、附完整代码 补录与分享本科实验,以示纪念。 一、实验要求 在词法分析、语法分析和语义分析程序的基础上,将C−−源代码翻译为中间代码。 要求将中间代码输出成线性结构(三地址代码&#…

企业级Web项目中应该如何做单元测试、集成测试和功能测试?

先自我介绍下: 本人有过10年测试经验,也参与过公安部网络安全产品测试交付、华为4G 网络设备测试交付、腾讯QQ空间APP产品测试交付。 关于“企业级Web项目中应该如何做单元测试、集成测试和功能测试”这个问题,我想给大家唠唠,我…

38 - 换座位(高频 SQL 50 题基础版)

38 - 换座位 -- 方法一 select(casewhen id%21 and id(select max(id) from seat) then idwhen id%20 then id-1else id1end) as id, student fromseat order byid;-- 方法二selectif(id%20,id-1,if(id(select max(id) from Seat),id,id1)) as id,student fromSeat order by id…

陀螺仪LSM6DSV16X与AI集成(7)----FIFO数据读取与配置

陀螺仪LSM6DSV16X与AI集成.6--检测自由落体 概述视频教学样品申请源码下载主要内容生成STM32CUBEMX串口配置IIC配置CS和SA0设置串口重定向参考程序初始换管脚获取ID复位操作BDU设置设置量程设置FIFO水印设置速率使用流模式设置FIFO时间戳批处理速率使能时间戳FIFO状态寄存器演示…

Django数据驾驶舱

Django数据驾驶舱 1.项目介绍2.项目结构3.库表结构3.1 appcsdn的models3.2 appssq的models3.3 appweather的models3.4 appweibo的models 4.功能展示5.解决问题5.1 路由配置5.2 后端数据与前端echarts展示5.3 长图表丝滑滚动条 6.遗留问题7.资源分享 1.项目介绍 这里介绍本人最…

阿里云发送验证码流程

目录 1. 阿里云短信服务简介 2. 阿里云验证码发送流程 2.1 申请阿里云短信服务 2.2 短信模板及阿里云秘钥 1.开发者可以在自己的应用程序中集成短信发送功能。绑定发起测试的手机号,需要绑定的手机号才能成功发送验证码,其他的用户手机号发送的验…

如何在 Ubuntu 12.04 VPS 上安装和配置基本的 LDAP 服务器

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 LDAP(轻量级目录访问协议)是一种通过文件和目录层次结构管理相关信息的协议,它可以从集中位置管…

【4003】基于springboot实现的线上阅读系统

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:spring…

ARM裸机:基础了解

ARM的几种版本号 ARM内核版本号 ARMv7 ARM SoC版本号 Cortex-A8 芯片型号 S5PV210 ARM型号的发展历程 m microcontroller微控制器 就是单片机 a application应用级处理器 就是手机、平板、电脑的CPU r realtime实时处理器 响应速度快,主要用在工业、航天等领域 soc 、cpu、…

ubutu 18.04源码编译安装freeswitch 1.10.7支持视频通话——筑梦之路

软件版本说明 ubuntu版本18.04:https://releases.ubuntu.com/18.04.6/ubuntu-18.04.6-live-server-amd64.iso freeswitch 版本1.10.7:https://files.freeswitch.org/freeswitch-releases/freeswitch-1.10.7.-release.tar.gz spandsp包:https:…

VB计算圆柱体积和表面积

已知圆半径和圆柱的高,计算圆柱体积和表面积。 Public Class Form1Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.ClickConst PI 3.14159Dim r As Integer, h As IntegerDim t As Single, s As Singler Val(TextBox1.Text)h V…

免杀笔记 ---> C语言

这次的更新可能有点慢,因为这段时间也比较忙,加上C语言还得和汇编结合,导致小编一个知识点总是得反复揣摩(太菜了),所以免杀的更新篇幅长度可能会达到两个月和三个月,但是小编能保证&#xff0c…