文章目录

  • 《Python 网络爬虫 Scrapy框架》
  • 第一章
    • 解析HTML的库
    • 解析XML/HTML的语法
    • 多层级网页爬取逻辑
    • 保存数据和展示数据
  • 第二章
    • 垂直搜索爬虫
    • 安装Scrapy爬虫框架
    • 创建并启动Scrapy爬虫工程
    • 整体把握scrapy工程
    • 爬虫请求流程
    • 审计 scrapy 框架
  • 第三章:数据提取和多层级网页爬取
    • 明确进度和目标
    • Response 对象
    • 核心1:xpath选择器和css选择器
    • 核心2:多层级网页爬取(主要问题的解决)
  • 定制爬虫的主要问题解决
    • 迭代的问题
    • 定位元素问题
  • 第四章:数据保存到csv文件
    • Feed exports
  • 定制
    • 请求添加 Cookie

《Python 网络爬虫 Scrapy框架》

全文主要参考《Python 网络爬虫 Scrapy框架》- 肖睿 陈磊 / 主编 - 刘信杰 王莹莹 秦丽娟 / 副主编,人民邮电出版社。

书籍章节目录如下

通读前两章,以及书籍章节目录,前4章可以拿来用,后续章节可能会用到的有 Scrapy反反爬技术、分布式爬虫Scrapy+Redis,后续的将来再说,把握当下。

第一章

把握4个概念:lxml库、xpath语法、多层级网页爬取逻辑、数据保存和展示。

解析HTML的库

请求网页URL并得到 HTML 源码后,需要解析 HTML 源码得到想要的数据,lxml库就是解析html的一个第三方库。

Python标准库自带xml模块,能解析xml文件和html页面内容,但性能和接口不够人性化。而第三方库lxml用Cython实现,增加很多使用功能,其大部分功能存在 lxml.etree 中。

使用 lxml 库提取网页内容步骤如下:

  1. 导入相应类库:from lxml import etree

  2. 使用HTML()方法生成待解析对象:tree=etree.HTML(html),其中html是目标页面的html源码

  3. 调用待解析对象的xpath()方法 tree.xpath(),填入xpath语句作为参数进行html解析

解析XML/HTML的语法

xpath是一套用于解析XML/HTML的语法,使用 路径表达式 选取xml/html中的节点集。值得一提的是,编写xpath需要熟悉html的元素。

多层级网页爬取逻辑

网页嵌套问题:抓取一个网页的数据容易,但如何抓取该网页嵌套的网页?即让爬虫有规律地抓取 所有嵌套的详情页

这种情况涉及爬虫的多层级网页爬取逻辑,以两层网页为例整理爬取逻辑:

  1. 请求第一层网页(目标数据是嵌套页的链接)
  2. 使用xpath解析网页,获取嵌套页的链接
  3. 遍历嵌套页链接,逐一发送请求
  4. 使用xpath解析第二层网页,获取最终目标数据
  5. 保存目标数据

此处应有爬虫算法,比如 Scrapy 使用的深度优先算法,数据结构学了的,见 浅谈网络爬虫中深度优先算法和简单代码实现。

保存数据和展示数据

把 URL-Method-Params-Status-Title-Length 格式的数据保存成 csv 文件,或者 txt 文件?后面还有处理考虑的问题,需要对这些目标资源进行分类吗?不分类数据量过大,除非压缩每个url的请求量,要么就分类,这些是fuzz时需要考虑的事情。

当下只需要考虑,保存数据的可读性,具体点就是阅读的舒适性。后期fuzz可能会保存为txt或csv,但目前我个人更想保存成 py,因为编辑器读起来舒适。

参考 csv、txt和tsv数据文件的异同点,以及如何使用Python读取和生成:通常来说,为了更好的用多种语言处理数据,推荐将数据存为csv格式(csv文件是以逗号分隔的一个文本文件,可以直接更改后缀为与其他类型文件),可同时在excle、python、matlab、sas和R等语言中切换自由简易,数据格式不受损!

选择:把 URL-Method-Params-Status-Title-Length 格式的数据保存成 csv 文件。

一天即将结束,回顾当天并没有实质性的成果,写出爬虫才是目标,其它的都是假的。

第二章

垂直搜索爬虫

根据使用场景,把爬虫分为通用搜索爬虫、垂直搜索爬虫,其中垂直搜索爬虫在运行时尽量只抓取与需求相关的网页信息,这里主要使用垂直搜索爬虫。

安装Scrapy爬虫框架

参考 Windows环境安装Scrapy框架步骤,本地执行命令 pip3 install scrapy 一步到位了

创建并启动Scrapy爬虫工程

开发 Scrapy 爬虫工程,要使用 Scrapy 命令创建爬虫工程,该工程是半成品爬虫项目。在命令行创建爬虫工程的步骤如下

  1. 创建爬虫工程:scrapy startproject 工程名
  2. 切换到工程根目录
  3. 创建爬虫文件:scrapy genspider 爬虫名 起始URL
  4. 启动爬虫工程:scrapy crawl 爬虫名
#创建爬虫项目并运行爬虫
scrapy startproject helloSpider
cd helloSpider
scrapy genspider test http://127.0.0.1/DVWA-master/
scrapy crawl test           # 工程根目录执行#执行回显模块
[scrapy.utils.log]
[scrapy.crawler]
[scrapy.extensions.telnet]
[scrapy.middleware]
[scrapy.core.engine]
[scrapy.extensions.logstats]
[scrapy.downloadermiddlewares.retry]
[scrapy.downloadermiddlewares.robotstxt]# helloSpider/spiders/test.py文件
import scrapyclass TestSpider(scrapy.Spider):name = 'test'allowed_domains = ['http://127.0.0.1/DVWA-master/']start_urls = ['http://http://127.0.0.1/DVWA-master//']def parse(self, response):pass

部分执行结果如下,可以看到打印内容有些混乱。

整体把握scrapy工程

创建项目的文件结构如下,过滤了项目配置文件 scrapy.cfg,因为开发爬虫时无需改动该文件。如图 Scrapy 爬虫工程主要由5个模块组成:爬虫、items模块、中间件模块、数据保存模块、配置模块,接下来简单说明各个模块。

Scrapy 框架的引擎和调度器暂时忽略

#流程图代码
graph TB
A(项目根目录helloSpider)
B(helloSpider)
B3(spiders)
B4(items.py)
B5(middlewares.py)
B6(pipelines.py)
B7(settings.py)
A-->B
B-->B3
B-->B4
B-->B5
B-->B6
B-->B7
b31(test.py)
B3-->b31

(1)spiders 文件夹:是 Scrapy 爬虫工程的爬虫模块,可以有多个爬虫文件。设计理念是方便一站一爬虫,而爬虫可以共用工程中的其它模块,提高复用和开发效率。

爬虫文件的内容显而易见,值得注意的是该爬虫默认无状态,因此 Scrapy 框架允许在爬虫文件中通过重写 start_requests()方法自定义对爬虫起始页面的爬取设置。

(2)items.py 文件:爬取的数据有可能需要在各模块之间传输,因此在 items.py 中定义统一的数据格式。

(3)pipelines.py 文件:Pipeline是管道的意思,是框架中的数据处理模块,常用于完成数据的持久化工作,还可以实现爬取数据的过滤、去重等工作。

(4)middlewares.py 文件:Middlewares 是中间件的意思,中间件的存在方便了爬虫框架的功能扩展。在 Scrapy 爬虫框架中 middleware 分为 downloader 、spider两类。

(5)settings.py 文件:Settings 模块承担了设置爬虫行为模式、模块启用等配置功能,在爬虫框架中是非常重要的模块。列举部分在开发中常用的配置:

  1. pipeline模块的启动以及启用顺序配置
  2. spider爬取网页数据的频率、默认Headers等属性配置
  3. 启动或关闭指定的spider middleware配置、downloader middleware配置

爬虫请求流程

结合第三章的部分内容,列出执行流程。

# 流程图代码
graph TB
a(启动爬虫)
b(引擎访问start_urls获取URL)
c(引擎调用Downloader模块下载网页)
d(引擎把下载结果传递给Spider的parse方法)
e(用户处理Response类对象response提取数据)
a-->b
b-->c
c-->d
d-->e

接下来第三章内容,终于要涉及到编写爬虫和落地的问题了(数据处理和数据保存)

目前了解 scrapy 工程的执行流程,但不清楚 scrapy 引擎是如何运行的、scrapy 的入口文件是哪一个、尤其是如何定义的请求类,这些对二开非常重要。所以接下来,审计一下 scrapy 框架的源码。

审计 scrapy 框架

审计先放着,主要目标是定制爬虫,别迷失在知识海洋。

框架文件和入口文件,显而易见入口文件是 __main__.py 文件:

请求类 Request:在 scrapy 根目录下看到 http 文件夹,该目录下的 __init__.py 文件定义请求类:class Request(object_ref)

scrapy 通过 Request 类对象发起请求,参考:python——scrapy中Request参数。

第三章:数据提取和多层级网页爬取

明确进度和目标

第二章重写了 start_requests(self) 方法,在 test.py 文件中包含如下变量,会随着目标的改变而改变:

当前爬虫变量 说明
allowed_domains 允许爬取的网址,不定义时会爬取所有网页,即通用搜索爬虫
start_urls 爬虫起点网页
cookies 身份验证

在完成了第一个网页的访问后,本章需要完成两个任务:数据的筛选提取、多层级网页爬取。

Response 对象

爬虫访问网页后,返回包含网页结果的 response 对象给 parse() 方法,其常用属性和方法如下表:

属性或方法 说明
url 当前返回页面对应的url
status HTTP请求状态码
meta 用于在 request 和 response 之间传递数据
body HTTP请求的返回数据(html或json),即数据处理的数据源
xpath() 使用 xpath() 选择器解析网页
css() 使用 css 选择器解析网页

meta属性:meta 属性存在的原因是,在某些场景下书爬取不是一次就能够完成的,比如爬取淘宝商品时,首先在列表页面爬取商品标题、价格、以及商品详情页面URL,然后使用该 URL 再次爬取商品详情页获取详细描述,合并两次爬取结果才是全部内容。这个需求在 scrapy 爬虫框架中通过 meta 来实现。

body属性:scrapy 爬虫框架提供了自己的 html 解析工具,即 xpath 选择器和 css 选择器,但爬取下来的数据格式并不一定都是 html 。如果网站使用了 前后端分离技术 ,则从数据接口爬取下来的数据格式是 Json,此时只能通过 body 属性获取原始数据,然后使用第三方库解析 Json 数据。

核心1:xpath选择器和css选择器

xpath 选择器基于 lxml 开发,Scrapy 爬虫框架支持 xpath 选择器提取网页数据,将选择器的接口整合到了 Response 类中。

使用 lxml 定位网页元素,无需其他操作即可通过返回值获得对应数据,但 Scrapy 爬虫框架使用 xpath 表达式定位网页元素后,方法返回值的对象是 Selector 。要想获取真正的目标数据,还要调用 extract() 方法提取数据。

使用 extract() 方法从 Selector 提取数据时需要注意 3 点(提高程序健壮性):

  1. extract() 方法返回值类型是 列表 ,还需要通过列表索引获取指定数据
  2. 空列表时,调用索引会引发程序异常
  3. extract_first()可以获取第一个匹配的元素,没有元素时会返回 none

xpath 常用语法如表,但组合非常灵活,需要结合实例不断练习

表达式 描述
nodename 选取此节点的所有子节点
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的为自豪
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性

核心2:多层级网页爬取(主要问题的解决)

爬取网站数据除了设置入口网页 start_urls 外,还要让爬虫实现自我驱动,按照设定的程序逻辑爬取所有符合条件的网页数据。对此,在使用第三方库开发爬虫时需要通过 循环等流程控制语句 来实现,而在 Scrapy 爬虫框架将以更优雅简便的方式实现 多层级页面 的爬取。

相同结构页面爬取,比如分页站点的数据爬取。

不同结构网页爬取,如分页网页的列表页和详情页的页面结构不同,这是处理列表页面的 parse() 方法不再适用,需要指定新的方法处理详情页的数据。实现很简单,在构造 Request 对象时,添加 callback 参数指定网页下载结果的处理方法即可。
(不设置callback参数时,默认使用 parse() 方法处理)

定制爬虫的主要问题解决

页面结构不会对南瓜爬虫有影响,只需要考虑定位什么元素,以及访问如何迭代两个问题。补充:还有一个URL的去重问题。

安全开发三大算法问题:数组去重、页面相似度比较、流程控制。

定制爬虫涉及其中两个问题:数组去重算法筛选URL、流程控制实现多层级网页爬取。

一般爬虫判断网页结构是否相同,会涉及页面相似度算法,而流程控制的问题,Scrapy 爬虫框架帮我们解决了,所以只需要解决 URL 去重问题。

多线程的问题也被 Scrapy 爬虫框架解决了。

迭代的问题

相同结构页面爬取中有提到:获取新的URL之后,在 parse() 方法中使用该 URL 构造 Request 对象,然后通过 yield 关键字将 Request 对象作为方法的返回值返回。Request 对象随后会被 Scrapy Engine 获得并转发给 Scheduler 模块进行调度,由 Downloader 模块下载网页代码,最后再传给 parse() 方法以完成新页面的解析。

简单来说,直接在 parse() 中迭代即可。

值得注意的是,网站一般都会有 访问频率限制 ,因此需要在 settings.py 文件中添加代码限制爬虫频率:

#设置每次爬取的间隔为 1 s,实际编写中使用通用的大写字母
Download_delay=1

Scrapy 爬虫迭代方式:在 parse() 方法中使用新的 Url 构造 Request 对象。(重写 start_requests方法是对爬虫起始页面的自定义爬取设置)。通过这种迭代方式,如果我们获取了链接 a ,则构造 yield scrapy.Request(url=url)
问题一,创建新的 Request 对象,需要重新设置爬虫信息吗,比如 Cookie ?(待测试)(测试结果是需要)
问题二,在构造之前我们需要检查该链接是否已经爬取过,可以为 class 定义一个列表 accessed_href 专门用来比较。

在迭代的过程中遇到一个问题:通过 yield scrapy.Request(url=complete_a) 进行迭代,发现并没有经过 parse() 处理,甚至难以确定是否访问。参考 关于Python Scrapy框架 yield scrapy.Request(next_url, call_back="")无法翻页情况解决,修改 allowed_domains ,并添加参数 dont_filter=True,成功解决无法迭代的问题。

完成迭代的 parse() 代码:

    def parse(self, response):start_url = "http://127.0.0.1/DVWA-master/"soup = BeautifulSoup(response.body, 'lxml')     # type: <class 'bs4.BeautifulSoup'>form_list = soup.find_all('form')  # 返回一个列表input_list = soup.find_all('input')a_list = soup.find_all('a')param_list = []a_href = []# 只处理单表单,有多个表单给出提示即可。2个表单变量form_info = str(len(form_list)) + "个表单"# 值得注意,input 也有链接,比如按钮跳转的网页。根据有无name属性,区分成两种数据:参数和链接for input in input_list:if input.get('name') and "submit" not in str(input).lower():param_list.append(input.get('name'))print(form_info, response.url,  param_list, response.status, soup.title, len(response.body))# 保存到 csv 文件# 获取所有超链接,检查后决定是否遍历complete_a = ""for a in a_list:url = a.get('href')if "http" in url and self.start_url not in url:     # 判断页面为无关continueelif url == ".":continueelse:if start_url in a.get('href'):  # 绝对路径a_href.append(url)complete_a = urlelse:                           # 相对路径a_href.append(start_url + url)complete_a = start_url + urlif complete_a not in self.accessed_href:self.accessed_href.append(complete_a)# print(complete_a)yield scrapy.Request(url=complete_a, dont_filter=True, cookies=self.cookie)

定位元素问题

天下苦 html 久矣,借阅相关书籍把 html 搞了吧。图书馆搜索两本不错的书如下,机械工业出版社的书一直印象很好,然后引进的翻译书籍主要考虑更加落地底层的设计和原理,所以选择了这两本书,明天借阅到手翻翻就知道效果了。

书名 作者 出版社 出版时间
《HTML》 (美)埃文斯(Evans)著 科学出版社 1996.7
《HTML5基础与实践教程》 吕云翔等编著 机械工业出版社 2020

提取数据的目标格式是:URL-Method-Params-Status-Title-Length,其中

需要考虑的数据 说明
URL 目前简单看了元素 link 和元素 a,暂时只考虑超链接 a 元素
Method 有表单收集表单,没表单搜集 Get
Params 如Method

关于 Method 参数提交方式(前后端数据交互),参考 Web页面向后台提交数据的方式和选择,主要分为三种:通过表单提交、通过网页链接提交、通过ajax提交。

通过ajax提交:Javascript支持ajax方式创建HTTP请求,可以通过在HTML页面元素的事件处理函数中创建ajax请求,在url参数里携带所需提交的参数,从而提交到后台,这种方式提交后页面不会刷新。

如何提取页面要提交的参数信息?先检测 form 表单,其它方式另开文章学习前端提交数据方式,然后再补充。

靶场 说明
DVWA <form method=""><input type="" name="">
sql-labs 该靶场前端没有参数信息,只有文字hint,有时候会是这样,比如旅馆id页的遍历
pikachu <form method=""><select name=“id”><input type="" name="">
bwapp <form method=""><input type="" name="">

如何定位 form 表单?xpath 定位需要详细的位置信息,而 form 标签的层级和值都是未知。考虑 xpath 、 regular expression 、bs4之后,选择 Python 的库 bs4 来定位 form 标签。

参考 python3解析库BeautifulSoup4,Python爬虫数据提取方式——使用bs4提取数据。首先查找 form 标签,然后从表单中筛选出 method 和 params,最后保存或者打印即可。(一个网页最好只有一个表单,但可以拥有多个表单,默认一个表单,多表单则提示)

Input类型:不能定位所有的 input 标签,因为有可能是超链接按钮,比如 DVWA 的某页代码如下。当前有参数、按钮两种类型。

<input type="button" value="View Help" class="popup_button" id="help_button" data-help-url="../../vulnerabilities/view_help.php?id=upload&amp;security=impossible" )"="">

parse() 提取数据部分代码如下,

    def parse(self, response):# 只处理单表单,有多个表单给出提示即可。2个表单变量soup = BeautifulSoup(response.body, 'lxml')     # type: <class 'bs4.BeautifulSoup'>form_list = soup.find_all('form')  # 返回一个列表form_info = "一个表单"if len(form_list) > 1:form_info = str(len(form_list)) + "个表单"# 值得注意,input 也有链接,比如按钮跳转的网页。根据有无name属性,区分成两种数据:参数和链接param_list = []input_list = soup.find_all('input')for input in input_list:if (input.get('name')) and (input.get('name') != "Submit"):param_list.append(input.get('name'))print(form_info, response.url,  param_list, response.status, soup.title, len(response.body))

第四章:数据保存到csv文件

Feed exports

保存数据的两种方式:爬取网站信息后,还需要将爬取的数据保存,给后续的数据分析等工作提供数据资源。保存数据的方式可以分为两大类:直接保存在文件中、保存到数据库中。文件格式以 Csv 和 Json 居多,这两种格式是数据分析领域常用的文件格式,能够结构化地保存爬取地数据,有利于数据读取与分析工作。

定制

请求添加 Cookie

设置Cookie的方式,参考 scrapy中如何设置应用cookies

 # 重写 start_requests()方法,测试成功def start_requests(self):start_urls = ['http://127.0.0.1/DVWA-master//']cookies = {"security": "impossible","PHPSESSID": "9nvum4l9mpfaejgjqljlvdqpp0",}proxies = {'http': 'http://localhost:8080', 'https': 'http://localhost:8080'}for url in start_urls:yield scrapy.Request(url=url, cookies=cookies)

【Web漏洞扫描这件事】爬虫2-scrapy框架相关推荐

  1. Web漏洞扫描(三:Burp Suite的基本操作)

    任务二.Burp Suite基础Proxy功能: 2.1.在Kali虚拟机中打开Burp Suite工具并设置,打开"Proxy"选项卡,选中"Options" ...

  2. 自研分布式web漏洞扫描平台WDScanner

    WDScanner 为了能在漏洞爆发后快速形成漏洞检测能力,同时能对网站或主机进行全面快速的安全检测,Tide安全团队(www.tidesec.net)开发了一套简单易用的分布式web漏洞检测系统WD ...

  3. Web漏洞扫描工具(批量脱壳、反序列化、CMS)

    一.什么是Web漏洞扫描工具 即是指"扫描Web应用以查找安全漏洞(如跨站脚本,SQL注入,命令执行,目录遍历和不安全服务器配置)的自动化工具",其中许多可能是由不安全或不正确的编 ...

  4. web漏洞扫描之AWVS

    文章目录 简介 下载地址 安装教程 开启 扫描测试 AWVS忘记了密码? 简介 本篇文章是在基于kali中安装,windows安装awvs可以参照此博客 AWVS是一个自动化的web漏洞扫描工具,它可 ...

  5. 【安全工具】全!十大Web漏洞扫描工具

    十大Web漏洞扫描工具 Acunetix Web Vulnerability Scanner[( 简称AwVS ) AwVS是一款知名的Web网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,检测流行 ...

  6. 常见的Web漏洞扫描分析工具

    常见的Web漏洞扫描分析工具: (1)Acunetix Web Vulnerability Scanner(简称awvs) 是一款知名的网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,监测流行安全漏 ...

  7. 10、 WMAP Web漏洞扫描

    一.Wmap简介 Wmap本身不是一个独立的漏洞扫描器,而是作为Metasploit的一个模块,结合web漏洞和web服务相关的模块协同工作,完成目标服务器的扫描.也就是说,如果我们 想要使用Wmap ...

  8. Web 漏洞扫描工具 AppScan 和 AWVS 使用方式

    Web 漏洞扫描工具 AppScan 和 AWVS 使用方式 文章目录 Web 漏洞扫描工具 AppScan 和 AWVS 使用方式 0x01 AppScan 基本操作 1.AppScan 简介 1. ...

  9. Acunetix WVS安装、破解+Web漏洞扫描

    云安全Web漏洞扫描 一.试验要求 二.试验目的 三.试验环境 四.试验内容 任务一 Acunetix WVS安装 任务二 Acunetix wVS的基本使用 一.试验要求 1.掌握web扫描的概念. ...

最新文章

  1. 程序员每天工作摸鱼俩小时,月薪35K?
  2. openCV滑动条TrackBar事件实例
  3. 为什么说神经网络可以逼近任意函数?
  4. 主流浏览器和内核及Web标准
  5. python日志配置文件解释_python 之 logger日志 字典配置文件
  6. Linux(Ubuntu)内存查询top命令详解
  7. bzoj1334 [Baltic2008]Elect
  8. android非法字符 ufeff,Java-在Android Studi上编译时出现错误(1,1)非法字符'\ ufeff'...
  9. Spring 的 ApplicationEvent and ApplicationListener
  10. HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效...
  11. Joyoshare VidiKit教程:如何将字幕添加到WMV电影中?
  12. Hawk 浩客 K950 3.0 免开机互拷易驱线 新产品 新科技
  13. Unix/Linux编程实践教程(1)---Unix系统编程概述
  14. 软件设计师-计算机系统知识
  15. 生成BDS卫星1和卫星2的B1C信号的数据分量主码、 导频分量主码和子码
  16. Android 之度量单位px,dp,dip,sp,in,mm详解
  17. 世界十大著名黑客 居然还有苹果创始人!
  18. lightoj1224 DNA Prefix
  19. 饿了么交易系统 5 年演化史
  20. Eclipse - subclipse svn

热门文章

  1. Android Intent隐式启动通过scheme打开应用
  2. api和sdk有什么区别
  3. python excel 数据匹配_VLOOKUP函数将一个excel表格的数据匹配到另一个表中
  4. 2020电工(高级)考试题及电工(高级)考试题库
  5. 怎样在百度地图上标注上自己公司的名称使别人能在搜索百度地图的同时在地图上能看见本公司地址?
  6. 势函数和鞅的停时定理
  7. 什么是加密数字货币 加密数字货币的发展前景
  8. angular5学习系列之基础知识
  9. 数据采集中间件技术对比V1.0
  10. linux安装特定版本软件,ubuntu16.04通过apt-get安装指定版本和查询指定软件有多少个版本...