本次爬虫网址:http://jandan.net/ooxx

前言:

前段时间一直在折腾基于qqbot的QQ机器人,昨天用itchat在微信上也写了一个机器人,相比webqq,微信的web端功能比较丰富,图片、文件等都可以传输。今天闲来无事准备给写个爬虫丰富微信机器人的功能,就想到了爬煎蛋网上面的图片。

说做就做,打开浏览器一看,渲染前的源码里是没有图片地址的。这个很正常,首先想到的就是异步请求去获取例如json格式的图片地址,然后渲染在页面上。于是用Chrome的全局搜索功能尝试搜了一下某一张图片的地址,结果居然是没有搜到。早就耳闻煎蛋被爬虫弄得苦不堪言,看来也开始采取一些措施了。于是去GitHub上搜了一下jiandan关键词,按时间排序,发现靠前的几个项目要不就没意识到煎蛋的反爬从而还是在用原来的方式直接处理源码,要不就是在用selenium(web自动化框架,可参考我的这篇文章:点击打开链接)进行爬虫。看来这个简单的这个反爬机制是最近一个月才用上的,很不凑巧被我撞上了。用selenium确实是一种万能、省力的方式,但实在太耗费性能。我在我阿里云的服务器上放了一个selenium+chromeheadless的微博爬虫,每次爬虫运行的时候服务器都非常卡。加上对煎蛋的反爬机制挺好奇的,于是我就准备通过分析js来找出图片的请求地址。

正文:

首先查看js渲染前的html源码,发现放图片的位置是这样的

本该放地址的地方赫然放着blank.gif,并且在onload属性上绑定了一个jandan_load_img函数。这个jandan_load_img就成为本次爬虫的突破所在了。继续ctrl+shift+F全局搜索,找到这个函数

function jandan_load_img(b) {var d = $(b);var f = d.next("span.img-hash");var e = f.text();f.remove();var c = f_K1Ft7i9UekcAhptpgQlLRFFKpzH6gOr0(e, "n8DpQLgoyVr2evbxYcQyFzxk9NRmsSKQ");var a = $('<a href="' + c.replace(/(\/\/\w+\.sinaimg\.cn\/)(\w+)(\/.+\.(gif|jpg|jpeg))/, "$1large$3") + '" target="_blank" class="view_img_link">[查看原图]</a>');d.before(a);d.before("<br>");d.removeAttr("onload");d.attr("src", location.protocol + c.replace(/(\/\/\w+\.sinaimg\.cn\/)(\w+)(\/.+\.gif)/, "$1thumb180$3"));if (/\.gif$/.test(c)) {d.attr("org_src", location.protocol + c);b.onload = function() {add_img_loading_mask(this, load_sina_gif)}}
}

果然就是这个函数在处理图片相关的标签,写在一个单独的js文件里。容易看到,第7、8行将a标签插入到img之前,查看源码看到a标签就是是查看原图的链接,也就是我们接下来爬取的时候用到的地址了。第6行f_后跟着一长串字母的这个函数(简称f函数)返回的就是图片地址。第7行中replace函数的作用是当图片为gif时替换中间的一个字符串为large。

那么接下来的任务就是分析f函数到底是怎么获取图片的地址的。首先看参数,第一个参数e为img-hash标签的text,第二个参数则是一个常量。这个常量我实测是会变化的,所以需要我们去请求这个js文件然后用正则去匹配到该常量。js文件的地址则写在了html源码里,文件名应该也是会变化的,也是用正则去匹配到。拿到常量之后接下来仍然使用chrome全局搜索(注:最好是打上断点跳过去,同一个js文件里的第605行和第943行有两个f函数可能会造成干扰,参见本文评论区),找到f函数,我发现此函数只是在做一些md5、base_64加密等操作,并不算复杂,可以将js代码转为python运行。当然也可以选择直接运行js,不过应该也是比较耗费性能的。我在转化成python代码的过程中,在base64解码上耗费了较长时间,也说明了自己在字符编码方面的知识比较薄弱。

下面是我对转换的一点解释,把一些无意义的ifelse等代码精简掉,再把代码分成五块之后,f函数长这样:

var f_K1Ft7i9UekcAhptpgQlLRFFKpzH6gOr0 = function(m, r, d) {var q = 4;r = md5(r);var o = md5(r.substr(0, 16));var l = m.substr(0, q);   var c = o + md5(o + l);var k;m = m.substr(q);k = base64_decode(m);var h = new Array(256);for (var g = 0; g < 256; g++) {h[g] = g}var b = new Array();for (var g = 0; g < 256; g++) {b[g] = c.charCodeAt(g % c.length)}for (var f = g = 0; g < 256; g++) {f = (f + h[g] + b[g]) % 256;tmp = h[g];h[g] = h[f];h[f] = tmp;}var t = "";k = k.split("");for (var p = f = g = 0; g < k.length; g++) {p = (p + 1) % 256;f = (f + h[p]) % 256;tmp = h[p];h[p] = h[f];h[f] = tmp;t += chr(ord(k[g]) ^ (h[(h[p] + h[f]) % 256]));}t = t.substr(26);return t
};

转换得到的python代码也相对应地分成五块之后如下:

def parse(imgHash, constant): q = 4constant = md5(constant)o = md5(constant[0:16])l = imgHash[0:q]c = o + md5(o + l)imgHash = imgHash[q:]k = decode_base64(imgHash)h =list(range(256))b = list(range(256))for g in range(0,256):b[g] = ord(c[g % len(c)])f=0for g in range(0,256):f = (f+h[g]+b[g]) % 256tmp = h[g]h[g] = h[f]h[f] = tmpresult = ""p=0f=0for g in range(0,len(k)):   p = (p + 1) % 256;f = (f + h[p]) % 256tmp = h[p]h[p] = h[f]h[f] = tmpresult += chr(k[g] ^ (h[(h[p] + h[f]) % 256]))result = result[26:]return result

这样对比之下应该就比较清晰了,基本上就是逐行翻译。另外base64需要重写一下。

最后就是一些普通的http请求操作了,以及使用itchat进行图片传输。所有代码已经上传到github上,后续有时间我打算添加上ip代理等新功能。没有系统学习过python所以代码可能不太规范,希望大家多多交流。项目地址:点击打开链接

另附本次爬虫的思维导图:

温馨提醒:虽然煎蛋肯定还有其他反爬措施,大家在爬虫过程中请务必遵守基本的互联网秩序,具体是啥相信大家都懂滴。

参考资料:

python base64解码incorect padding错误:点击打开链接

写于2017年12月6日晚

编辑于2018年2月6日晚

python爬虫之反爬虫情况下的煎蛋网图片爬取初步探索相关推荐

  1. python爬虫图片实例-Python爬虫爬取煎蛋网图片代码实例

    这篇文章主要介绍了Python爬虫爬取煎蛋网图片代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天,试着爬取了煎蛋网的图片. 用到的包: ...

  2. python爬图代码实例_Python爬虫爬取煎蛋网图片代码实例

    这篇文章主要介绍了Python爬虫爬取煎蛋网图片代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天,试着爬取了煎蛋网的图片. 用到的包: ...

  3. Python爬虫爬取煎蛋网图片代码实例

    这篇文章主要介绍了Python爬虫爬取煎蛋网图片代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天,试着爬取了煎蛋网的图片. 用到的包: ...

  4. Python爬虫入门教程【15】:煎蛋网XXOO图片抓取

    今天写一个爬虫爱好者特别喜欢的网站煎蛋网http://jandan.net/ooxx,这个网站其实还是有点意思的,网站很多人写了N多的教程了,各种方式的都有,当然网站本身在爬虫爱好者的不断进攻下,也在 ...

  5. Python爬虫之煎蛋网图片下载

    受程序员群的影响(自己污的本性),他们总是带我开车,想想我也该收集一些资料了(美女图片) 代码 import requests from lxml import etreeurls = ['http: ...

  6. Python爬虫:煎蛋网图片URL解密处理

    转自:https://yukunweb.com/2018/5/jiandan-encryption-processing/?page=1 俞坤的博客 最近一直有朋友问我改版的煎蛋网妹子图怎么爬,因为他 ...

  7. Python爬虫项目实操——【3】美空网数据爬取

    1.美空网数据-简介 从今天开始,我们尝试用2篇博客的内容量,搞定一个网站叫做"美空网"网址为:http://www.moko.cc/, 这个网站我分析了一下,我们要爬取的图片在 ...

  8. Python爬虫入门教程【3】:美空网数据爬取

    美空网数据----简介 从今天开始,我们尝试用2篇博客的内容量,搞定一个网站叫做"美空网"网址为:http://www.moko.cc/, 这个网站我分析了一下,我们要爬取的图片在 ...

  9. python爬图片_Python爬虫:彼岸图网图片爬取-Go语言中文社区

    杂 哈哈,这是我第一篇博客 半年以后回来再看发现这代码简直太难看了 现在已经弃用大小驼峰转蛇形命名了 确实好看 除了命名别的也写的不怎么样 因为爬虫只是个爱好所以也不准备再投入时间重构了 将就着看吧 ...

最新文章

  1. 官方数据:5次SDN大会的背后
  2. 滚动条的出现导致居中的元素会晃动
  3. Scala基础教程(一):简介、环境安装
  4. 【机器视觉】 assign算子
  5. redis中几种数据存储方式的比较
  6. 2 未匹配到任何借口_拼多多【关键词精确匹配溢价】给你想要的精准流量,让你订单暴增的秘诀...
  7. mysql增数据语句_Mysql 数据增删改查语句
  8. FarMap诞生了!
  9. mysql语句1=1_mysql - “where 1 = 1”语句
  10. 设置图例 边框 背景 AE C#
  11. 元组可以直接添加进数据库吗_AWS Neptune 详细体验:OLTP的可扩展图数据库
  12. python3.7.2怎么用不了pillow_python怎么加载Pillow包
  13. 深度学习之神经网络(二)
  14. docker alpine中 配置 nginx和php两个容器互联时,访问php文件不执行问题
  15. C# 根据出生日期解析 对应星座
  16. 轩小陌的Python笔记-Pandas时间序列与日期
  17. 你有一份七夕赚钱指南等待签收
  18. thinkphp 官网教程
  19. 征途私服mysql启动不了_征途服务器架设需要的LINUX版本
  20. UVA12096 - The SetStack Computer(set + map映射)

热门文章

  1. 手游《奔跑吧?骚年!》技术分享(四):矩形碰撞检测
  2. PHP RSA公钥加密解密
  3. C#.NET开源项目、机器学习、商务智能
  4. 无法实例化xxx对象
  5. 【技巧插件】PDF文件转换为CAD文件
  6. 美工效果图大小 html,六、DIV CSS实战之布局美工图分析与切图
  7. 电磁波波长越短能量越强_电磁波扫盲篇:频率,波长,速度,温度,能量的关系...
  8. 海德汉Heidenhain免授权320、530、620、640等数据采集方案
  9. 带式输送机、采样控制系统、变速器、离心成型机、齿轮减速器、三级减速器、蜗轮减速机、多向混合机、颗粒包装机、机床夹具、球阀、支撑掩护式液压支架、轮式移动机器人、液压传动、轴向柱塞泵…毕业设计 课程设计
  10. Moov itom not found 视频修复