本文作者韦玮原创,转载请注明出处。

项目需求与问题引入

有时,我们想爬取腾讯动漫中的漫画,比如,我们不妨打开腾讯动漫中某一个动漫的网址ac.qq.com/Comic/comic…,如下图所示:

然后,我们点击“开始阅读”,出现如下所示界面:

可以看到,在此有一副漫画,我们可以按常规方式尝试进行处理,我们查看该网页对应的源代码,可以发现在源代码中并不能找到这副漫画的图片地址,并且,当我们鼠标往下滑动的时候,才会触发加载后续的漫画,所以,我们可以初步断定,这种数据是通过异步加载动态触发出来的。

按照一贯的解决思路,我们接下来尝试使用抓包分析进行解决这个问题,所以我们打开Fiddler。

打开Fiddler之后,我们再次打开动漫页拖动触发出相应的漫画,与此同时,Fiddler中会依次出现新触发的资源信息,如下所示:

我们依次分析这些网址,并把漫画相关的网址整理复制出来,放到word中,如下所示:

通过对比观察,我们可以看到漫画资源的网址规律。

对应的规律如下:

ac.qq.com/store_file_download?buid=动漫ID&uin=uin值&dir_path=/&name=日期_随机数_漫画图片ID.jpg

我们可以看到,其地址中有一段是随机数,这一段网址我们很难通过以往的网址构造的方法构造出来,所以,即使分析出了网址规律也无济于事,因为这个网址的规律中有一部分是随机数,即无规律的字段。

所以,显然,这种网址动态触发+资源随机存储的反爬策略我们采用以往的反爬攻关技巧很难解决,这一点大家可以先按常规的方法尝试写一遍便会有深刻感触。

问题的解决办法总是有的,只要我们思考,接下来,我们就为大家讲解这一种反爬策略应该如何攻克解决,今天我们的主要需求与目的是使用Python自动爬取腾讯动漫里面的各个漫画,实现自动加载触发漫画并得到随机地址的功能,以此为例为大家讲解网址动态触发+资源随机存储的反爬策略的攻克方式。

问题难点与解决思路

由上面的介绍,我们可以知道,目前问题的难点在于:

1、漫画图片动态触发,异步加载,无法通过漫画的主网址获得这些各漫画图片的网址,而没有漫画图片的网址,我们无法爬取这些漫画图片。

2、漫画图片网址中含有随机参数,即使我们通过抓包分析分析出各漫画网址的规律,也无法主动构造出这些漫画图片的地址。

这些问题其实我们可以解决,先为大家介绍一下解决思路,解决思路如下:

1、通过PhantomJS(无界面浏览器)自动触发出漫画图片。

2、通过JS代码实现页面滑动,以自动触发出剩下的多张漫画图片。

3、触发出漫画图片之后,将漫画地址通过正则表达式提取出来。

4、交给Urllib或者Scrapy普通爬虫,对相关资源进行自动爬取,在这里我们使用Urllib模块编写相关爬虫。

在这里稍微解释一下,PhantomJS虽然可以触发相关的数据,因为其本质就是浏览器,但是其效率是比较慢的,所以,一般情况下,我们会将主要爬虫处理部分交给Urllib或者Scrapy等常规爬虫,这样效率高,而如果常规爬虫不能处理的部分,我们可以将这一部分交给PhantomJS等处理,处理完成后交由常规爬虫处理,也就是不同的技术负责不同的部分,整合起来写,这样可以让爬虫的效率更高,并且不影响爬虫的功能。

使用PhantomJS实现动态触发动漫图片地址的获取

接下来,我们就来编写实现相关的项目。

首先,我们导入相关模块:

from selenium import webdriver
import time
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

然后,我们需要基于PhantomJS创建一个浏览器,并且设置一下用户代理,否则可能出现界面不兼容的情况,如下所示:

dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = ("Mozilla/4.0 (compatible; MSIE 5.5; windows NT)" )
browser = webdriver.PhantomJS(desired_capabilities=dcap)

然后,我们通过PhantomJS打开相关动漫网页,将相关动漫图片地址触发出来,如下所示:

#打开动漫的第一页

browser.get("ac.qq.com/ComicView/i…")

#将打开的界面截图保存,方便观察

a=browser.get_screenshot_as_file("D:/Python35/test.jpg")

#获取当前页面所有源码(此时包含触发出来的异步加载的资源)

data=browser.page_source

#将相关网页源码写入本地文件中,方便分析

fh=open("D:/Python35/dongman.html","w",encoding="utf-8")

fh.write(data)

fh.close()

随后,我们运行相关代码,运行完成后,会发现对应的截图D:/Python35/test.jpg如下所示:

​可以看到,前面几幅漫画图片成功加载,可是后面的漫画图片却没有加载出来,为什么呢?

显然后面的漫画图片我们需要触发才能加载,所以我们可以使用JS代码实现自动拖动触发后面的漫画的功能。

在没有触发后续的漫画图片之前,我们不妨看一下此时的网页源代码,我们在源代码中搜索“ac.tc.qq.com/store_file_download”,即搜索满足漫画图片资源的网址格式的地址,看看源码中有没有,如下所示:

​可以看到,此时只有4各匹配的网址,说明此时确实没有加载出相关的剩下的动漫图片资源网址。

接下来,我们可以通过window.scrollTo(位置1,位置2)实现自动滑动页面,触发后续的网址,我们可以在上面的:

browser.get("ac.qq.com/ComicView/i…")

代码下面插入如下补充代码:

for i in range(10):

js='window.scrollTo('+str(i*1280)+','+str((i+1)*1280)+')'

browser.execute_script(js)

time.sleep(1)

通过该循环,我们可以依次进行自动滑动,模拟滑动后自然会触发后续的图片资源。

随后,我们再次执行代码,执行完代码后,截图中你可以看到剩下的动漫图片资源已经加载出来了,并且源码中,匹配的网址也变多了,源码中网址的匹配情况现在如下所示:

​可以看到,此时符合规律的网址已经变成了25个,所以,现在,当前页面中的所有图片资源已经加载出来了。

显然,我们通过PhantomJS已经实现了异步资源触发与随机网址获取的功能了。接下来我们将需要提取出相关动漫图片的网址,并交由Urllib模块进行后续爬取。

结束了PhantomJS的使用之后,我们需要关闭一下浏览器,所以,我们在代码后添加如下一行代码:

browser.quit()

编写完整爬虫项目

随后,我们继续编写该爬虫项目。

我们可以通过正则表达式'<img src="(http:..ac.tc.qq.com.store_file_download.buid=.*?name=.*?).jpg"'将所有动漫资源图片网址提取出来,提取出来之后,通过urllib对这些图片进行爬取,爬到本地。

具体代码实现如下:

import re
import urllib
#构造正则表达式提取动漫图片资源网址

pat='<img src="(http:..ac.tc.qq.com.store_file_download.buid=.*?name=.*?).jpg"'

#获取所有动漫图片资源网址

allid=re.compile(pat).findall(data)

for i in range(0,len(allid)):

#得到当前网址

thisurl=allid[i]

#去除网址中的多余元素amp;

thisurl2=thisurl.replace("amp;","")+".jpg"

#输出当前爬取的网址

print(thisurl2)

#设置将动漫存储到本地的本地目录

localpath="D:/Python35/dongman/"+str(i)+".jpg"

#通过urllib对动漫图片资源进行爬取

urllib.request.urlretrieve(thisurl2,filename=localpath)

随后,我们运行该代码,便可以在本地目录D:/Python35/dongman/下看到如下信息:

​可以看到,相关动漫图片资源已经爬到本地了。

为了方便大家调试,我们提供完整代码,完整代码如下所示:

from selenium import webdriver

import time

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

import re

import urllib.request

dcap = dict(DesiredCapabilities.PHANTOMJS)

dcap["phantomjs.page.settings.userAgent"] = ("Mozilla/4.0 (compatible; MSIE 5.5; windows NT)" )

browser = webdriver.PhantomJS(desired_capabilities=dcap)

#打开动漫的第一页

browser.get("ac.qq.com/ComicView/i…")

for i in range(10):

js='window.scrollTo('+str(i*1280)+','+str((i+1)*1280)+')'

browser.execute_script(js)

time.sleep(1)

#将打开的界面截图保存,方便观察

a=browser.get_screenshot_as_file("D:/Python35/test.jpg")

#获取当前页面所有源码(此时包含触发出来的异步加载的资源)

data=browser.page_source

#将相关网页源码写入本地文件中,方便分析

fh=open("D:/Python35/dongman.html","w",encoding="utf-8")

fh.write(data)

fh.close()

browser.quit()

#构造正则表达式提取动漫图片资源网址

pat='<img src="(http:..ac.tc.qq.com.store_file_download.buid=.*?name=.*?).jpg"'

#获取所有动漫图片资源网址

allid=re.compile(pat).findall(data)

for i in range(0,len(allid)):

#得到当前网址

thisurl=allid[i]

#去除网址中的多余元素amp;

thisurl2=thisurl.replace("amp;","")+".jpg"

#输出当前爬取的网址

print(thisurl2)

#设置将动漫存储到本地的本地目录

localpath="D:/Python35/dongman/"+str(i)+".jpg"

#通过urllib对动漫图片资源进行爬取

urllib.request.urlretrieve(thisurl2,filename=localpath)

可以看到,当我们直到了解决方法之后,项目实现起来并不难,在这里,大家需要通过这一个例子,掌握这一类问题的解决思路,即掌握网址动态触发+资源随机存储的反爬策略的攻克解决方案。希望大家可以多多练习,希望这篇文章能够让遇到这一类问题的同学获得解决的思路与启发。

本文作者韦玮原创,转载请注明出处。

作者新书推荐

转载于:https://juejin.im/post/59b0ae6051882524272611ce

腾讯动漫爬虫与动态随机加载反爬破解技术实战相关推荐

  1. Python爬虫第二课 Selenium介绍和反爬技术

    selenium的介绍 知识点: 了解 selenium的工作原理 了解 selenium以及chromedriver的安装 掌握 标签对象click点击以及send_keys输入 1. seleni ...

  2. Python网络爬虫之图片懒加载技术、selenium和PhantomJS

    引入 今日概要 图片懒加载 selenium phantomJs 谷歌无头浏览器 知识点回顾 验证码处理流程 今日详情 动态数据加载处理 一.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素材ht ...

  3. React 中动态的加载组件 ---loadable-components

    loadable-components 用于在react 中动态的加载组件 安装方法: npm i loadable-components 使用: 引入: 代码中使用: 希望对你有所帮助

  4. js如何动态的加载js文件

    在这个地方我说的动态的加载js文件是通过调用函数来加载js文件,我们在这个地方通过一个简单的小例子来实现 首先创建3个文件分别为:test1.html,test1.js,demo.js test1.j ...

  5. nginx php动态编译加载模块.

    #Nginx动态编译加载模块步骤 #查看目前Nginx版本及编译模块 #[root@centos7 ~]# /opt/app/lnmp/nginx-1.12.0/sbin/nginx -V #ngin ...

  6. 【Android 逆向】Android 进程注入工具开发 ( 远程进程注入动态库文件操作 | 注入动态库 加载 业务动态库 | 业务动态库启动 | pthread_create 线程开发 )

    文章目录 前言 一.加载 libnattive.so 动态库 二. libnattive.so 动态库启动 三. pthread_create 线程开发 四. 线程执行函数 前言 libbridge. ...

  7. 【Android NDK 开发】Android.mk 配置动态库 ( Android Studio 配置动态库 | 动态库加载版本限制 | 本章仅做参考推荐使用 CMake 配置动态库 )

    文章目录 I . Android Studio 中使用 Android.mk 配置动态库 总结 II . 第三方动态库来源 III . 配置 Android.mk 构建脚本路径 IV . 预编译 第三 ...

  8. linux程序加载器,Linux 动态连接加载器 ld-linux用法

    Linux 动态连接加载器 ld-linux用法 文章作者:网友投稿 发布时间:2009-12-10 16:21:11 来源:网络 ld-linux有两种用法,间接调用和直接调用. 间接调用时,连接器 ...

  9. ELF动态库加载技术

    库用于将相似函数打包在一个单元中.Linux支持两种类型的库:静态库(在编译时静态绑定到程序)和动态库(在运行时绑定到程序).Linux系统使用的动态库是ELF格式,后缀名为so. 1 加载 动态库内 ...

最新文章

  1. springboot的jsp应该放在哪_web项目jsp放在哪里 Spring Boot 静态资源处理(4)
  2. Java学习之SpringBoot整合SSM Demo
  3. ssh提示connection refused_2020高考语法填空必会技巧之有提示词(一)
  4. 用python直接调用asr技术_python中asr
  5. 机器学习基础(五十五)—— 核(Kernel Trick)
  6. 编写跨浏览器兼容的 CSS 代码的金科玉律
  7. Open Virtual Machine Tools
  8. 视频基本知识  AD转换和YUV,cb cr基本知识
  9. 几个维度带你了解什么是聚合支付
  10. 全新内测!mac剪映专业版v1.4.0重磅出击!
  11. 验证(15位或者18位)身份证号码的正确正则表达式
  12. NFC芯片群读应用,RFID娱乐筹码、棋子FPC定制标签
  13. itop4412 uboot 学习详细记录四丶Exynos4412 编译Makefile的配置文件config.mk分析)
  14. 苦瓜红烧肉这么做,每次做连汤汁都不剩
  15. HTML5期末大作业:响应式旅游风景家乡网站设计——衢州旅游网站(5页) HTML+CSS+JS 旅游网页设计成品 dw旅游景点介绍网页制作
  16. 明翰全日制英国硕士留学攻略V2.7(持续更新)
  17. 读书笔记_卓越程序员密码
  18. 分享一个漂亮的NetBeans配色方案
  19. 计算机网络中常用设备处于脱机状态,win7网络正常网页提示处于脱机状态该怎么解决?...
  20. 【2.0版】监测数据处理系统-自动导出监测日报表、周报表及月报表(基坑监测、地铁监测)V2.0

热门文章

  1. openstack e版创建instance整个流程
  2. 【程序员轶事】程序员的1927年12月31日午夜一秒谜案
  3. Sealed,new,virtual,abstract与override的区别
  4. XamarinEssentials教程清空键值
  5. Xamarin XAML语言教程基本页面ContentPage占用面积(二)
  6. Xamarin XAML语言教程对象元素的声明方式
  7. 编译包含Google Play服务App的SDK版本问题
  8. 通过因特网连接Beaglebone Black
  9. Nmap扫描教程之DNS服务类
  10. php直接修改excel,php如何修改excel