Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >利用 Chrome DevTools 把微博打包成 zip 文件

利用 Chrome DevTools 把微博打包成 zip 文件

作者头像
zgq354
发布于 2020-02-17 03:52:39
发布于 2020-02-17 03:52:39
1.3K00
代码可运行
举报
文章被收录于专栏:0x00010x0001
运行总次数:0
代码可运行

过去在微博遇到许多有趣的内容,但常常因为时间太久远,回看收藏链接往往返回的是404,记忆也随之变成了一个个空洞。脑洞打开,是不是可以把一条微博涉及到的各种文件一键打包下载,在本地阅读呢,就像 docx 文档格式一样。

技术方案

从尽可能简单的角度解决问题的角度出发,能在浏览器端完成的话最好,不需要依赖什么脚本和平台,额外花时间去梳理各种业务逻辑相关的琐事。从此出发,在数据来源方面,选择更简单的手机版;保存数据,优先考虑在浏览器端用文件相关的 API 实现。

理论上来说,文件的本质是一系列二进制数据集合,HTML5 FileAPI 提供了处理二进制数据对象的 Blob。在浏览器环境中字符串可以构造成 Blob,微博中涉及到的图片和视频文件的数据也通过 Blob 的方式处理。

有了 Blob 这一层抽象,文件打包压缩的需求,也用 Blob 的方式去实现的话会更自然一些。寻找已有的解决方案,发现 JSZip,它支持创建 zip 的文件,在输入输出的表达上支持包括 Blob 在内的多种格式,也支持 ArrayBuffer, Base64, 字节数组等等方式的表达,省下不少自己处理的功夫。

文件下载方面,可以用 URL.createObjectURL 基于 Blob 创建一个 Object URL,然后创建一个 <a> 元素,触发 click 事件下载,得到最终的文件。

把数据源与保存的方式都理清楚,大致有了一个流程,就可以动手了。

在运行环境方面,不需要额外安装什么,只需要一个 DevTools 即可,开发者工具提供了 Snippets(代码片段)功能,可以直接在里面写那些需要在注入到页面的代码片段然后运行,很方便。参考这篇文章

下面是实现的思路:

数据的获取

1. 基础数据

微博移动版为减少请求,会在 HTML 输出该条微博的信息,在 $render_data.status 里。

2. 评论与转发

直接上 Networks 面板,定位到相关的 HTTP 请求,然后右键 Copy as fetch,即可得到基于 fetch 的请求代码。

把代码梳理之后抽象成如下函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async function fetchWeibo(url) {
  return await fetch(
    url,
    {
      credentials: "include",
      headers: {
        accept: "application/json, text/plain, */*",
        "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
        "mweibo-pwa": "1",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "x-requested-with": "XMLHttpRequest",
        "x-xsrf-token": getCookie('XSRF-TOKEN')
      },
      referrer:
        `https://m.weibo.cn/status/${$render_data.status.bid}`,
      referrerPolicy: "no-referrer-when-downgrade",
      body: null,
      method: "GET",
      mode: "cors"
    }
  ).then(r => r.json());

  function getCookie(key) {
    return document.cookie
      .split("; ")
      .map(item => item.split("="))
      .reduce((accu, curr) => {
        accu[curr[0]] = curr[1];
        return accu;
      }, {})[key];
  }
}

async function fetchWeiboComments(max_id = 0, max_id_type = 0) {
  return await fetchWeibo(
    `https://m.weibo.cn/comments/hotflow?id=${$render_data.status.id}&mid=${$render_data.status.mid}&max_id=${max_id}&max_id_type=${max_id_type}`
  );
}

由于分页的关系,实际抓取时需要传最后一条评论的 id 才可获取下一页,考虑到热门的微博评论和转发太多,直接抓取并不现实,且会给服务器带来额外的压力,微博的 robots.txt 不给我们这么干,本着学习研究的初心,这里抓两页就收工。

评论与转发也同理,这里就不贴了。

3. 图片与视频等资源的获取

$render_data.status.pics 我们可得到微博配图的 URL,$render_data.status.page_info.media_info,可以得到视频的 URL。遍历的时候 fetch ,相应请求的时候调用 response.blob() 让这个请求返回对应的 Blob。

但这里有个问题,微博配图和视频都不是同一个域名之下的资源,会受到 CORS 机制 的限制,微博返回的请求也没有对应的 CORS 头部,自然会被拦截。

为了解决跨域拦截问题,找到一个代理工具 Cors Anywhere,它提供一个 HTTP 服务,只需要在目标 URL 前加入它的地址,按原样请求原始地址,并在返回的响应头中加上对应的 Access-Control-Allow-Origin:

抓取的请求可以包装为一个函数,corsProxyServerCors Anywhere 的地址:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const corsProxyServer = '';
async function fetchBlob(url) {
  return await fetch(`${corsProxyServer}${url}`, {
    credentials: "omit",
    referrer: `https://m.weibo.cn/detail/${$render_data.status.id}`,
    referrerPolicy: "no-referrer-when-downgrade",
    body: null,
    method: "GET",
    mode: "cors"
  }).then(r => r.blob());
}

项目主页提供了一个运行在 Heroku 的例子,一般图片都比较大,测试发现下载速度感人,不如在本地搭建一个。

搭建很简单,git clone, npm install 运行一把梭,但是就有一个问题,本地运行的服务开放的端口是 http 的,在 https 的站点对一个 http 的站点发 XHR 会被拦截,需要考虑域名与 https 证书的配置,带来的则是一堆繁琐的事情。

我只是想跑一个小服务,能不能简单点?当然能!这时候祭出一大神器:whistle

whistle 是一个基于 Node 实现的 Web 请求调试代理工具,支持 HTTP, HTTPS, WebSocket 的请求的修改和转发,通过编写 whistle 配置,可以实现各种非常灵活的功能。

一条 whistle 配置解决一切蛋疼:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cors.proxy 127.0.0.1:8888

打包压缩

(我只是一个调包侠

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const zip = new JSZip();
zip.file("content.json", statusDataBlob);
zip.file("interaction.json", interactionDataBlob);

const picsFolder = zip.folder("pics");
imgBlobList.forEach(item => {
  const { pid, smBlob, lgBlob } = item;
  picsFolder.file(`${pid}.${smBlob.type.split('/')[1]}`, smBlob);
  picsFolder.file(`${pid}.large.${lgBlob.type.split('/')[1]}`, lgBlob);
});

const videosFolder = zip.folder("videos");
videoBlobList.forEach(item => {
  const { bid, videoBlob, videoHDBlob } = item;
  videosFolder.file(`video-${bid}.${videoBlob.type.split('/')[1]}`, videoBlob);
  videosFolder.file(`video-${bid}-hd.${videoHDBlob.type.split('/')[1]}`, videoHDBlob);
});

const finalResultBlob = await zip.generateAsync({
  type: "blob",
});

下载

开头已介绍过思路,直接上代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const a = document.createElement('a');
a.download = `weibo-${$render_data.status.bid}-${dateStr}.zip`;
a.href = URL.createObjectURL(finalResultBlob);
a.click();

查看器的设计

单纯实现下载并不够,所以特地花了半天时间用 TypeScript 基于 React 做了个查看器,用 JSZip 解压,然后再生成 Object URL 直接展示。

做这个查看器的时候尝试了 Parcel,做一些小的项目的确是很舒心,不会在一开始的时候就陷入各种 Webpack 配置的泥潭无法自拔。唯一需要留意的是 tsconfig.json 需要手动配置一下,不然在写 .tsx 组件的时候 VSCode 的代码提示会有问题。

写完连着下载代码一块传到了 Github,起了个名儿叫 weibo-zip,地址:zgq354/weibo-zip

查看器的页面也放了一个,若你有兴趣可以体验体验:https://zgq354.github.io/weibo-zip/

后来上传了一些例子,parcel 默认没有直接拷贝文件的操作,搜索一番发现了 parcel-plugin-asset-copier

总结

关于控制台写脚本爬网页数据

优势:

  1. 只要有浏览器就能跑
  2. 不用考虑模拟登录等琐碎问题,直接拥有登录态
  3. 可以减少环境差异带来的坑:比如说这里遇到了一处微博返回的 JSON 的 Date 字符串在 Python 会出现解析失败的问题,但在 JS 里面 new Date('xxx') 是正常返回的。

劣势:

  1. CORS 跨域问题,导致不能拿来就用
  2. 请求有并发限制

综上,它比较适合简单处理一些小数据的抓取和处理。本来选择 Console 实现就是看准了它的便利性,但也因为需要手动解决跨域的问题,直接扼杀了它的实用性,所以只能算是个折腾玩具了哈哈~

React 有 Create React App 可以快速搭项目,但有时候并不想限制在这一套体系下,相比于一切都以 js 为中心的 Webpack,Parcel 会更自然一些。

在写一些自己玩的小东西的时候,用一些类似 Parcel 的工具可以快速出活,关注点也应多放在要解决的问题上。

参考

  1. 爬虫新姿势 - 使用Chrome Devtools写一个小说爬虫 - 掘金
  2. HTML5 FileAPI
  3. Blob
  4. HTTP访问控制(CORS) - HTTP | MDN
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-02-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
围观微博网友发起的美胸大赛
继上次知乎话题 拥有一副好身材是怎样的体验? 解析了知乎回答内容之后,这次我们来解析一下微博内容,以微博网友发起的美胸大赛为例:
爱写bug
2019/08/01
6.7K0
围观微博网友发起的美胸大赛
React引入jszip实现多个文件打包成zip下载
jszip文档 安装两个插件 yarn add jszip file-saver 可直接复制查看效果 import JSZip from 'jszip' import { saveAs } from 'file-saver' export default () => { //通过请求获取文件blob格式 function getFileBlob(url) { return new Promise((resolve, reject) => {
明知山
2022/05/05
2.6K0
React引入jszip实现多个文件打包成zip下载
Python解读:地摊经济火了,你想好摆摊去卖什么了吗?
【导语】:今天我们来聊聊地摊经济,Python技术部分请看第四部分。公众号后台,回复关键字“地摊”获取完整数据。
CDA数据分析师
2020/06/12
7460
昨晚中国女足绝地大逆转,爬取了微博评论区,评论很精彩
昨晚,女足16年后重夺亚洲杯,决赛落后两球,依然能保持对比赛的观察和思考,下半场从容调度人手,最后完成逆转。
润森
2022/09/22
3930
昨晚中国女足绝地大逆转,爬取了微博评论区,评论很精彩
围观微博网友发起的美胸比赛学习爬取微博评论内容
继上次知乎话题 拥有一副好身材是怎样的体验? 解析了知乎回答内容之后,这次我们来解析一下微博内容,以微博网友发起的美胸大赛为例:
爱写bug
2019/07/15
1.6K0
一不小心,我爬取了100万条微博评论
↑ 关注 + 星标 ~ 有趣的不像个技术号 每晚九点,我们准时相约 郑重声明:本项目及所有相关文章,仅用于经验技术交流,禁止将相关技术应用到不正当途径,因为滥用技术产生的风险与本人无关 大家好
朱小五
2020/03/10
1.3K0
一不小心,我爬取了100万条微博评论
微博数据各字段的含义
最近在写微博的爬虫,框架已经基本稳定,但是在解析各字段含义的环节卡了好几天,因为不清楚各个字段的含义,官网的api注释好像有点过时,很多字段没有注释,所以只能自己一点一点分析了
李玺
2021/11/22
1.6K0
远程URL文件批量下载打包的方法
想法很好,并且已经有人这样做了,我们只用考虑按照别人的做法坐下去 前端打包有两个前提:
seth-shi
2023/12/18
3390
python实现在线微博数据可视化
完整代码gitee地址:https://gitee.com/lyc96/weibo
Python研究者
2020/09/28
7800
python实现在线微博数据可视化
爬虫课程(十二)|ajax分析法(微博):通过获取api爬取新浪微博内容数据实战
一、回顾 我们之前利用Scrapy爬取豆瓣网站信息时,直接通过加载目标URL返回的Response得到想要的值。我也在后面爬取知乎网站时通过模拟登录的方式进入到目标URL,也是通过返回的Response得到需要的值。 这一次,我们将通过解析网站的HTTP请求去破解获取数据的API的方式去爬取想要的数据。 二、找出微博用户唯一标示:oid 一般做爬虫爬取网站时,首选的都是m站,其次是wap站,最后考虑PC站,因为PC站的各种验证最多。当然,这不是绝对的,有的时候PC站的信息最全,而你又恰好需要全部的信息,那
黄小怪
2018/05/21
6.7K0
python爬虫抓取新浪微博数据
新浪微博的数据是用ajax异步下拉加载的,在chrome的调试模式下可捕捉到相应的请求:
章鱼喵
2018/09/26
7.3K0
Scrapy框架的使用之Scrapy爬取新浪微博
前面讲解了Scrapy中各个模块基本使用方法以及代理池、Cookies池。接下来我们以一个反爬比较强的网站新浪微博为例,来实现一下Scrapy的大规模爬取。 一、本节目标 本次爬取的目标是新浪微博用户的公开基本信息,如用户昵称、头像、用户的关注、粉丝列表以及发布的微博等,这些信息抓取之后保存至MongoDB。 二、准备工作 请确保前文所讲的代理池、Cookies池已经实现并可以正常运行,安装Scrapy、PyMongo库。 三、爬取思路 首先我们要实现用户的大规模爬取。这里采用的爬取方式是,以微博的几
崔庆才
2018/06/25
1.8K0
爬取许嵩的所有微博并存入MongoDB
我很喜欢许嵩的音乐,我以前基本上他的每首歌都会唱,比如《素颜》、《灰色头像》、《玫瑰花的葬礼》、《清明雨上》、《庐州月》等等,打开播放器,基本上都是循环播放许嵩的歌,简直欲罢不能!
爱吃西瓜的番茄酱
2018/07/25
6970
爬取许嵩的所有微博并存入MongoDB
Python实现单博主微博文本、图片及热评爬取
文章简介 经常刷微博的同学肯定会关注一些有比较意思的博主,看看他们发的文字、图片、视频和底下评论,但时间一长,可能因为各种各样的原因,等你想去翻看某个博主的某条微博时,发现它已经被删除了,更夸张的是发现该博主已经被封号。那么如果你有很感兴趣的博主,不妨定期将Ta的微博保存,这样即使明天微博服务器全炸了,你也不用担心找不到那些微博了。(自己的微博也同理哦。) 看网上一些微博爬虫,都是针对很早之前的微博版本,而且爬取内容不全面,比如长微博不能完整爬取、图片没有爬取或没有分类,已经不适用于对当下版本微博内容的
慕白
2018/07/06
1.4K0
微博登陆爬取用户影响力
这里是需要微博用户登陆之后才可以查看的, 所以为了实现我们的需求,我们开始模拟登陆。
李玺
2021/11/22
3080
微博登陆爬取用户影响力
数据分析入门系列教程-微博热点
在前面,我们学习了爬虫的基本流程和必备技能,对于刚刚入门的人来说,打好基础,掌握基本步骤是最为重要的。
周萝卜
2020/10/10
5420
数据分析入门系列教程-微博热点
文件下载,搞懂这9种场景就够了
在 文件上传,搞懂这8种场景就够了 这篇文章发布之后,阿宝哥收到了挺多掘友的留言,感谢掘友们一直以来的鼓励与支持。其中掘友 @我的烟雨不在江南 和 @rainx 在文章底部分别发了以下留言:
童欧巴
2021/08/20
3.2K0
文件下载,搞懂这9种场景就够了
Flask实现微博画像采集小工具
Flask是Django之外用Python实现的另一优秀Web框架。相对于功能全面的Django,Flask以自由、灵活著称。在开发一些小应用的时候使用Flask就非常合适。本文将使用Flask开发一个微博用户画像的生成器。
李玺
2021/11/22
5230
Flask实现微博画像采集小工具
用Python对鹿晗、关晓彤微博进行情感分析
專 欄 ❈大吉大利小米酱,Python中文社区专栏作者,Python爱好者,顽强地自学中,18线灵魂画手/段子手/脑洞女王。 简书: http://www.jianshu.com/u/8e45f2f3b6c1 知乎: https://www.zhihu.com/people/otakurice ❈ 前言:本文主要涉及知识点包括新浪微博爬虫、python对数据库的简单读写、简单的列表数据去重、简单的自然语言处理(snowNLP模块、机器学习)。适合有一定编程基础,并对python有所了解的盆友阅读。 相
Python中文社区
2018/02/01
1.4K0
用Python对鹿晗、关晓彤微博进行情感分析
python和Ajax在一起了?真的???
有些时候我们使用浏览器查看页面正常显示的数据与使用requests抓取页面html得到的数据不一致,这是因为requests获取的是原始的HTML文档,而浏览器中的页面是经过JavaScript处理数据后的结果。这些处理过的数据可能是通过Ajax加载的,可能包含HTML文档中,可能经过特定算法计算后生成的。
Python研究者
2020/10/29
4510
python和Ajax在一起了?真的???
推荐阅读
相关推荐
围观微博网友发起的美胸大赛
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验