目标:爬取爱漫画上面自己喜欢的一个漫画

分析阶段:

0、打开爱漫画主页,迎面就是一坨js代码。。直接晕了

1、经过抓包和对html源码的分析,可以发现爱漫画通过另外一个域名发送图片,而当前域名中通过js动态生成图片的文件名。问题就在这里了,首先,图片的文件命名模式比较多,没办法通过js源码直接爬;其次,有两种不同的图片文件名表现形式,一种是字典,一种是通过运算后返回的字典字符串。所谓字典字符串,就是[a:b]变成"[a:b]"。

version 1:

var cInfo={"bid":862,"burl":"/comic/862/list_84410.html","bname":"\u0053\u006b\u0065\u0074\u0044\u0061\u006e\u0063\u0065","cid":84410,"cname":"\u7b2c\u0032\u0038\u0038\u8bdd","len":22,"files":["JOJO_001.jpg","JOJO_002-003.jpg","JOJO_004.jpg","JOJO_005.png","JOJO_006.png","JOJO_007.png","JOJO_008.png","JOJO_009.png","JOJO_010.png","JOJO_011.png","JOJO_012.png","JOJO_013.png","JOJO_014.png","JOJO_015.png","JOJO_016.png","JOJO_017.png","JOJO_018.png","JOJO_019.png","JOJO_020.png","JOJO_021.png","JOJO_022.png","JOJO_023.png"],"finished":1};

version 2:

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('E h={"i":"\\g\\e\\2\\f\\j\\n\\o\\m\\2","k":"/l/3/4.6","7":3,"5":"\\c\\d\\8\\9\\a","b":["w.0","F.0","D.0","B.0","C.0","G.0","K.0","L.0","J.0","H.0","I.0","A.0","s.0","t.0","r.0","p.0","q.0"],"u":y,"z":x,"v":1};',48,48,'png||u0065|862|list_83707|cname|html|bid|u0038|u0036|u8bdd|files|u7b2c|u0032|u006b|u0074|u0053|cInfo|bname|u0044|burl|comic|u0063|u0061|u006e|016|017|015|013|014|cid|finished|001|17|83707|len|012|004|005|003|var|002|006|010|011|009|007|008'.split('|'),0,{}))

我只能OTL。。

解决:

首先,可以发现,可以设计两种模式,一种是处理verson 1的方式,另一种是将verson 2转化为verson 1之后处理。

Google了下,发现有一个叫pyv8的库,可以动态解析js代码,而经过debug分析,找到了第2个版本中储存字典字符串的变量。但是这个变量在函数中,是局部变量。但分析到了这个地步,方案就简单了。

0、加一个全局变量hogo

1、在函数返回字典字符串之前,将字典字符串赋值给hogo

2、读取hogo的值

当然,最后记得要改header中的Referer,否则图片服务器给你404

全部代码:

  1. # -*- coding: UTF-8 -*-
  2. import re
  3. import urllib
  4. import urllib2
  5. import sys
  6. import PyV8
  7. import os
  8. # 爬取爱漫画《sketdance》的全章页面
  9. # 找到某一话
  10. # 分析文件名,下载全话图片
  11. # 通过执行js代码,找到具体的文件名。
  12. # 进入下一话
  13. mydir = r'd:/sketdance/'
  14. imghost = r'http://c4.mangafiles.com/Files/Images/'
  15. tarhost = r'http://www.imanhua.com'
  16. taraddr = r'http://www.imanhua.com/comic/862/'
  17. headers = {'Referer':'http://www.imanhua.com/comic/862/list_82877.html',\
  18. 'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36'}
  19. tarRequest = urllib2.Request(taraddr,headers=headers)
  20.  
  21. def downloadParts(url,title):
  22. print 'now is downloading ' + title + ':'
  23. print url
  24. print title.decode('gb2312').encode('gbk')
  25. os.mkdir(mydir + title.decode('gb2312').encode('gbk'))
  26. firststart = url.find('comic/') + len('comic/')
  27. firstslash = url.find('/',firststart)
  28. parturl = url[firststart:firstslash + 1]
  29. sestart = url.find('_',30)
  30. sefinis = url.find('.',sestart)
  31. parturl = parturl + url[sestart + 1:sefinis] + '/'
  32. partsRequest = urllib2.Request(url,headers=headers)
  33. while 1:
  34. try:
  35. page = urllib2.urlopen(partsRequest)
  36. except:
  37. pass
  38. else:
  39. break
  40. page = page.read()
  41. jscode = re.compile(r'<script type="text/javascript">(.+?)</script>')
  42. jscode = jscode.search(page)
  43. jscode = jscode.group(1)
  44. if jscode.find('split') != -1:
  45. jscode = 'var hogo;' + jscode
  46. start = jscode.find('return p')
  47. jscode = jscode[0:start] + 'hogo=p;' + jscode[start:]
  48. with PyV8.JSContext() as env1:
  49. env1.eval(jscode)
  50. vars = env1.locals
  51. jscode = vars.hogo
  52. fileinx = jscode.find('files":')
  53. fileinx = jscode[fileinx:]
  54. imgre = re.compile(r'([^"]+(\.jpg|\.png))')
  55. imglst = imgre.findall(fileinx)
  56. imglst = [key[0] for key in imglst]
  57. for index,key in enumerate(imglst):
  58. if key.find('.jpg') != -1:
  59. flag = '.jpg'
  60. else:
  61. flag = '.png'
  62. print imghost + parturl + key
  63. if index == 0:
  64. headers['Referer'] = url
  65. else:
  66. headers['Referer'] = url + '?p=' + str(index)
  67. imgRequest = urllib2.Request(imghost + parturl + key,headers=headers)
  68. while 1:
  69. try:
  70. img = urllib2.urlopen(imgRequest)
  71. except:
  72. pass
  73. else:
  74. break
  75. f = open(mydir + title + '/' + str(index) + flag,'wb')
  76. f.write(img.read())
  77. f.close()
  78.  
  79. def findTar(url):
  80. while 1:
  81. try:
  82. page = urllib2.urlopen(tarRequest)
  83. except:
  84. pass
  85. else:
  86. break
  87. page = page.read()
  88. first = u'SketDance漫画列表'
  89. first = first.encode('gb2312')
  90. index = page.find(first)
  91. start = index
  92. title = ""
  93. parts = u'第'
  94. parts = parts.encode('gb2312')
  95. while index != -1:
  96. index = page.find('title="' + parts,index)
  97. if index == -1:
  98. break
  99. finis = page.find('"',index + 7)
  100. title = page[index + 7:finis]
  101. start = page.rfind('href="',start,index)
  102. finis = page.find('"',start + 6)
  103. downloadParts(tarhost + page[start + 6:finis],title)
  104. index += 1
  105. start = index
  106. findTar(taraddr)

  

【原创】最近写的一个比较hack的小爬虫的更多相关文章

  1. iOS:自己写的一个星级评价的小Demo

    重新整理了下自己星级评价的Demo,可以展示星级评价,可以动态修改星级. github的地址:https://github.com/hunterCold/HYBStarEvaluationView a ...

  2. 最近写了一个红包雨的小功能,但感觉自己的js还有很多地方可以提高,望大神们可以帮忙指点一二

    js部分 'use strict'; function RedEnvelope(options){ if(this === window){ return new RedEnvelope(option ...

  3. 用Go写了一个相似Proxy的小程序,能够用来訪问goolge个人使用还是能够的.

    package main import ( "fmt" "io" "net/http" ) func main() { http.Handl ...

  4. Js 正则表达式 写了一个正整数或小数点或分数前两个正则表达式

    写了一个正整数或小数点或分数前两个正则表达式 /^[0-9]+([.]{1}[0-9]{1,2})? $/ 版权声明:本文博客原创文章.博客,未经同意,不得转载.

  5. 如何写好一个vue组件,老夫的一年经验全在这了【转】 v-bind="$attrs" 和 v-on="$listeners"

    如何写好一个vue组件,老夫的一年经验全在这了 一个适用性良好的组件,一种是可配置项很多,另一种就是容易覆写,从而扩展功能 Vue 组件的 API 来自三部分——prop.事件和插槽: prop 允许 ...

  6. 访问github太慢?我写了一个开源小工具一键变快

    前言 GitHub应该是广大开发者最常去的站点,这里面有大量的优秀项目,是广大开发者寻找资源,交友学习的好地方.尤其是前段时间GitHub公布了一项代码存档计划--Arctic Code Vault, ...

  7. 搞了我一下午竟然是web.config少写了一个点

    Safari手机版居然有个这么愚蠢的bug,浪费了我整个下午,使尽浑身解数,国内国外网站搜索解决方案,每一行代码读了又想想了又读如此不知道多少遍,想破脑袋也想不通到底哪里出了问题,结果竟然是web.c ...

  8. 用C3中的animation和transform写的一个模仿加载的时动画效果

    用用C3中的animation和transform写的一个模仿加载的时动画效果! 不多说直接上代码; html标签部分 <div class="wrap"> <h ...

  9. 写了一个常规性生成merge 的小脚本

    现在使用数据库来写存储过程,动不动参数就会用到xml ,当然罗,优势也很明显,参数相对固定,而且灵活,如果要修改或者什么的,中间接口层也不需要做变化,只需要修改封装的存储过程以及程序传参就ok了. 随 ...

随机推荐

  1. C++ map

    C++ map Map is an associative container that contains a sorted list of unique key-value pairs. That ...

  2. drupal进入不了后台时候的解决办法,作者使用drush方案,已验证

    drupal把正在用的主题不小心删了,怎么进后台? 方法一: 去variable表里把默认主题换了 方法二: ?q=user 登录到管理区,开启简洁连接使用user(网站根目录下面) admin/ap ...

  3. Cygwin的安装及在Android jni中的简单使用举例

    Cygwin是一个在windows平台上执行的类UNIX模拟环境,是cygnussolutions公司开发的自由软件.Cygwin是很多自由软件的集合,Cygwin的主要目的是通过又一次编译.将POS ...

  4. 两个Hacker,专门Patch TObject

    http://hallvards.blogspot.fr/2006/03/hack-8-explicit-vmt-calls.html http://www.deltics.co.nz/blog/po ...

  5. C++异常中的堆栈跟踪

    C++语言的运行时环境是基于栈的环境,堆栈跟踪(trace stack)就是程序运行时能够跟踪并打印所调用的函数.变量及返回地址等,C++异常中的堆栈跟踪就是当程序抛出异常时,能够把导致抛出异常的语句 ...

  6. Caused by: java.lang.ClassNotFoundException: org.aopalliance.intercept.MethodInterceptor

    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Fai ...

  7. SQL查询语句联系

    建立四个表,分别是学生表,课程表,成绩表和教师信息表 插入信息: 题目: 1. 查询Student表中的所有记录的Sname.Ssex和Class列 select Sname,Ssex,Class f ...

  8. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

  9. ios应用接入微信开放平台

    前几天试了一下服务端接入微信公众平台,昨天又看了一下APP接入开放平台 开放平台和公众平台的差别 公众平台针对的是公众账号,除了提供管理后台之外.也开放了若干接口,让微信server和开发人员自己的应 ...

  10. 黑马程序猿_ 利用oc的协议实现代理模式

    先说下代理模式是什么吧 定义: 为其它对象提供一种代理以控制对这个对象的訪问.在某些情况下,一个对象不适合或者不能直接引用还有一个对象 而代理对象能够在client和目标对象之间起到中介的作用. 在看 ...