贝城社区 - iBeiKe City - 北京科技大学官方互动交流论坛

 找回密码
 加入社区
查看: 1111|回复: 1

某漫画搬运网站的二三事(技术向)

[复制链接]
  • TA的每日心情
    慵懒
    2019-3-4 22:07
  • 签到天数: 40 天

    [LV.5] ☆ 常驻居民 ☆

    84

    帖子

    4457

    上传

    724

    积分

    Rank: 36Rank: 36Rank: 36Rank: 36

    发表于 2019-1-2 20:01:33 | 显示全部楼层 |阅读模式

    欢迎加入贝城社区,体验更多精彩服务!Join iBeiKe City Now

    您需要 登录 才可以下载或查看,没有帐号?加入社区

    x
    本帖最后由 Majolica 于 2019-1-7 01:41 编辑

    网站连接:http://www.zerobyw.com

    最近站长把服务器迁移到国外了,所以需要~翻墙~才能看。。
    有些漫画需要付费买会员才能看。。

    不过好在插件是随便写的,vip验证在前端,我就当他是默许我可以爬他的网站了吧。。

    此站使用discuz3.4搭建,据站长所说,插件是外包的,我相当于是抓住了一些漏洞绕过了vip验证,那么,关于以下内容还请大家不要生张。

    我们将讨论以下内容:

    (linux 环境下)

    1. 如何获取一部漫画某一章节的图片列表
    2. 如何获取一部漫画的全部章节
    2. 如何快速地下载(多线程)

    既然是linux下当然是写脚本啦~

    使用以下命令行工具:

    1. cUrl
    2. parallel

    进入正题

    STEP 1

    01.png

    如图,这是某部漫画。。

    02.png

    点击“检察元素”

    03.png

    我们看到,onclick时间调用了"xiazaitu"函数

    在控制台输入"xiazaitu",按住ctrl点击左键跳转到函数定义的地方:

    04.png

    最核心的代码就是选定的部分。
    虽然我平时都用axios发ajax请求,不过jquery之类的在这方面大同小异。

    回首分析xiazaitu函数有3个参数,一个挂载点的"el",一个神秘整数"zjid",一个章节名称"name"。

    1. jQuery.post('./plugin.php',{
    2.             id:'jameson_manhua:ajax',
    3.         zjid:zjid,
    4.         optype:'getimglist',
    5.         formhash:'c3d652cc'
    6.     })
    复制代码


    复制选定的ajax代码到控制台上。这显然是一个 POST 请求。

    现对传给服务器的参数进行分析:

    "/plugin.php"是discuz调用插件的入口;
    "id": 插件名与请求类型;
    "zjid": 神秘数字;
    "optype": 从缩写来看是操作类型(?);
    "formhash": discuz 用于 CSRF 检验的 token;

    显然,zjid 应当直接用传入xiazaitu函数的参数赋值,本例中为25775。

    稍加修改后发送请求:

    05.png

    点击“网络”,filter 一行选择XHR(意即Xml Http Request):

    07.png

    至此我们达到了一个小目标:获得某章节的漫画图片列表。

    STEP 2

    我们看到,神秘数字 zjid 是至关重要的。只要获得了某部漫画对应的全部章节和章节对应的 zjid ,我们就可以批量下载了。
    审查元素之后我们发现xiazaitu函数直接在 a 标签的 onclick 事件中被调用,所以我们只要爬虫爬下漫画目录页面(第一张图)对 html 字符串进行处理,就可以筛选出所有的 zjid 了。

    1. #!/bin/bash

    2. host="http://www.zerobyw.com"

    3. if [ ! $1 ]; then
    4.     echo "zjid not defined!"
    5.     exit 1
    6. fi

    7. if [ ! $2 ]; then
    8.     echo "formhash not defined!"
    9. fi

    10. if [ ! -s cookies ]; then
    11.     echo "cookies required!"
    12.     exit 2
    13. fi

    14. res=`curl -s -b cookies -d \
    15.     "id=jameson_manhua:ajax&zjid=$1&optype=getimglist&formhash=$2" \
    16.     "$host/plugin.php"`

    17. res=${res#\[}
    18. res=${res%\]}

    19. res=${res//\\\//\/}
    20. res=${res//\"/}
    21. res=${res// /%20}

    22. OLD_IFS="$IFS"
    23. IFS=","
    24. arr=($res)
    25. IFS="$OLD_IFS"

    26. for url in ${arr[@]}
    27. do
    28.     imgName=${url#http://mhua.zerobyw.com/manhua/*/}
    29.    
    30.     if [ ! -s $imgName ]; then
    31.         echo $url
    32.         mkdir -p ${imgName%\/*}
    33.         curl $url > $imgName -s
    34.     fi
    35.    
    36.     echo $imgName
    37. done
    复制代码


    这是对某一个 zjid 处理的脚本。
    我不喜欢 python ,所以不用。
    shell 大法好!!!

    使用方法是
    1. zero [zjid] [formhash]
    复制代码

    其中,zero 是脚本名,zjid是那个神秘数字,formhash是神秘哈希,上文提过。

    zjid 需要我们自己爬虫分析得到,formhash是根据访问者(用 cookie 控制)随机生成的。
    因此在接下来的 curl 请求构造中,我们需要保存一定的 cookie ,并在接下来一系列操作中携带此 cookie 。

    上述代码第19行"-b"实际上就是携带"cookies"文件里的cookie的意思。

    23 - 33 行将获得的结果转化成合适的字符串数组。
    因为使用了数组,所以第一行一定要加上"#!/bin/bash"。

    35 行开始是使用循环遍历url列表并下载

    怎么样?很简单吧。(以上内容如果出现了难懂的术语可以百度或者问问大佬们。)

    STEP 3

    接下来就是获取一部漫画对应全部 zjid 的部分了:

    1. #!/bin/bash

    2. if [ ! $1 ]; then
    3.     echo "Usage:"
    4.     echo "excalibur [kuid] [folder]"
    5.     exit 1
    6. fi

    7. folder="./"

    8. if [ ! $2 ]; then
    9.     echo "downloading into current folder..."
    10. else
    11.     folder=$2
    12.    
    13.     echo "downloading into $folder..."

    14.     if [ `mkdir -p $folder` ]; then
    15.         echo "error while create folder"
    16.         exit 1
    17.     fi
    18.    
    19.     cd $folder
    20. fi

    21. formhash=`curl -s -c cookies "http://www.zerobyw.com/plugin.php?id=jameson_manhua&c=index&a=ku" | grep '\<input type=\"hidden\" name=\"formhash\"' | awk '{print $4}'`

    22. formhash=${formhash#*\"}
    23. formhash=${formhash%\"}

    24. url="http://www.zerobyw.com/plugin.php?id=jameson_manhua&c=index&a=bofang&kuid=$1"

    25. array=(`curl -s -b cookies -c cookies $url | grep '<a href="javascript:;" onclick="xiazaitu(' | awk '{print $3}'`)

    26. len=${#array[@]}
    27. for((i = 0; i < $len; i++))
    28. do {
    29.     zjid=${array[$i]}
    30.     zjid=${zjid#*,}
    31.     zjid=${zjid%,*}
    32.     array[$i]=$zjid
    33. }
    34. done

    35. parallel --no-notice -j 20 zero ::: ${array[@]} ::: $formhash
    复制代码


    用法:

    1. excalibur [kuid] [folder]
    复制代码


    其中 excalibur 是脚本名(咳咳),kuid是漫画的id(第一张图的地址栏url里最后面的参数),folder就是要写入的目录名称了。

    第26行获取 formhash 和 cookie。awk,grep.sed合称linux三剑客来着,有兴趣自己查查看~

    33行获取 zjid 列表,简单粗暴

    35 - 43行对章节列表进行进一步处理,使用 for in 循环不能改变原数组的值,所以使用普通的 for 循环。

    第45行使用多进程工具 parallel ,三个冒号是传参的意思。<a>aaa</a>
    意思是,使用 parallel 调用 zero 指令,第一个参数是遍历 array 数组得到的,第二个参数是 formhash 的值。
    -j 20 表示 同时在工作的进程数最大为20。
    --no-notice是因为每次运行它会提示你“使用此工具请注明开发者,讨厌的话就花10000欧元来买啊”什么的...

    fin~
    人生如梦亦如歌,就如那是似水的年华般稍纵即逝,没有一点留恋...
  • TA的每日心情
    慵懒
    2018-11-10 06:02
  • 签到天数: 15 天

    [LV.4] ☆ 贝城访客 ☆

    1万

    帖子

    1万

    上传

    2万

    积分

    Rank: 30Rank: 30Rank: 30Rank: 30

    贝城社区·资源达人十大风云人物星座勋章·白羊

    QQ
    发表于 2019-3-12 21:46:09 | 显示全部楼层
    技术小白直接下了动漫花园推荐的弹弹play播放器,主要是可以直接关联动漫花园的资源下载
    北科掌机联机群:245721562,北科52v6漫群:18255742

    回复 支持 1 反对 0

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入社区

    本版积分规则

    手机版|封号查询|广告合作|免责声明|贝城社区 - iBeiKe City ( 京ICP备05065307号

    GMT+8, 2019-10-22 07:42

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表