网络爬虫是一种自动化工具,用于从网站上抓取结构化数据。Scrapy是一个Python框架,它利用Twisted异步网络框架加速数据下载,并通过一系列内置组件如中间件(Middleware)提供了强大的定制能力。
-
基础库:
urllib
:标准库的一部分,用于URL编码、基本HTTP请求等。- 正则表达式 (RegEx) 和
BeautifulSoup
或lxml
:解析HTML或XML文档,提取所需的数据。比如,lxml
是一个高性能的选择器库,支持XPath和CSS选择器。
-
高级框架:
Scrapy
:- 架构包括下载管理器(Downloader)、Spiders(负责发现并抓取网页)、Item Pipeline(处理抓取的数据)和中间件(处理请求/响应过程中的逻辑)。
Requests
:用于发送HTTP请求,简单易用且功能强大。Selenium
:针对JavaScript驱动的网站,可执行动态渲染以抓取内容。
-
进阶技术:
pyspider
或Scrapy
的扩展:提供更复杂的工作流管理和调度。- 验证码处理:可能涉及OCR识别、图片识别服务等。
- 动态渲染和模拟登录:通过Selenium控制浏览器行为,处理动态加载内容,有时需结合会话管理。
要继续学习网络爬虫,你可以:
- 深入理解Scrapy架构,特别是中间件如何工作。
- 学习如何使用XPath或CSS选择器从复杂的HTML中提取数据。
- 实践编写简单的Scrapy Spider,从网站抓取数据。
在Scrapy中设置自定义中间件通常涉及重写特定的中间件类方法。下面是一些关键步骤:
-
创建中间件类:
创建一个继承自scrapy.middleware.BaseMiddleware
的类,比如MyCustomMiddleware
。from scrapy import middleware class MyCustomMiddleware(middleware.BaseMiddleware): # ...
-
重写必要的方法:
process_request
: 当接收到一个新的请求时,这个方法会被调用。你可以在这里添加自定义的请求处理逻辑,如设置固定请求头。
def process_request(self, request, spider): request.headers['User-Agent'] = 'Your Custom User Agent' return None # 返回None表示继续处理请求
-
启用中间件:
在settings.py
文件中,添加你的中间件到DOWNLOADER_MIDDLEWARES
或SPIDER_MIDDLEWARES
中,具体取决于它是在下载阶段还是爬取阶段应用。DOWNLOADER_MIDDLEWARES = { 'your_project.MyCustomMiddleware': 543, # 可以调整顺序 }
-
测试中间件:
运行Scrapy爬虫,查看新设置的请求头是否生效。
记得在编写中间件时遵循Scrapy的命名约定和API文档,确保你的中间件能够与Scrapy的核心组件协同工作。
Scrapy的中间件(Middleware)允许你在请求和响应之间添加额外的功能,它们按照特定顺序执行。在这个过程中,Scrapy会确保依赖关系得到满足:
-
请求中间件:这些中间件在发送请求之前运行。在
process_spider_output
函数中,当scrapy.Item
实例被yield时,它会被传递到下一个中间件或直接进入下载器。你可以在这里做预处理,如打印消息确认item即将被提交。 -
下载中间件:在请求发送之后,但服务器响应到达之前运行。这通常用于修改请求头、重试失败的请求等。
-
下载完成中间件:处理每个完整响应后,即使响应已被错误地丢弃,也会运行一次。这个阶段适合处理解码后的响应数据。
-
物品管道中间件:最后,每个Item实例(
scrapy.Item
)会在进入Pipeline之前通过这些中间件。process_spider_output
中的yield语句就涉及到这一点,它表示Item将被传递给下一层处理。
中间件链可以通过在settings.py文件中定义MIDDLEWARES设置来配置。要理解依赖关系,关键是明确哪些中间件在何时以及以何种方式影响请求和响应流程。
-
Scrapy的架构设计包括一系列中间件,它们按顺序执行,每个中间件可以修改请求或响应。例如,
DownloaderMiddleware
用于处理下载过程中的逻辑,如重定向、代理设置;SpiderMiddleware
允许你在爬虫处理URL之前或之后添加自定义的行为。中间件的链式执行可以通过settings.py
文件中的DOWNLOADER_MIDDLEWARES
和SPIDER_MIDDLEWARES
进行配置。 -
使用XPath或CSS选择器在Scrapy中提取数据是关键技能。以CSS为例,假设你想从一个响应中获取标题,你可以这样写:
title = response.css('h1::text').get()
如果使用XPath,对应的表达式可能是:
title = response.xpath('//h1/text()').get()
-
编写一个简单的Scrapy Spider涉及几个步骤:
- 定义
Spider
类,继承自scrapy.Spider
,并设置名称、起始URL和解析方法。
class MySpider(scrapy.Spider): name = "myspider" start_urls = ["http://example.com"] def parse(self, response): title = response.css('h1::text').get() yield {"title": title}
- 使用
scrapy crawl myspider
命令运行爬虫。 - 调试和管理中间件可能需要查看日志文件。
- 定义
XPath和CSS选择器都是用于从HTML文档中定位特定元素的技术,但它们的设计目的和语法有所不同。
区别:
- XPath 是一种基于XML的查询语言,它允许通过节点关系、属性和文本内容来定位元素。XPath表达式通常更复杂,适用于大型、结构化的文档,如XML文档和某些复杂的HTML页面。
- CSS选择器 更专注于样式表,主要用于CSS(层叠样式表)应用。它主要依据元素的标签、类、ID、属性和它们之间的关系来选取元素,适合快速、直观地选择网页上的可见部分。
使用场景:
- 当你需要通过元素的复杂层次结构(如子元素、祖先元素)定位元素时,XPath更为合适。
- 如果你正在处理的是HTML文档,尤其是那些结构清晰、具有明确类和ID标识的页面,CSS选择器由于其简洁性和易读性,通常更适合查找元素。
示例:
- 使用XPath选取
<body>
下的第一个<h1>
元素://body/h1[1]
- CSS选择器选取所有拥有
.info
类的段落:.info p
XPath和CSS选择器都是用于从XML和HTML文档中选取节点的强大工具:
XPath():
- 支持基于路径的语言,如
/html/body/div[@class='myClass']
,可以指定节点的位置和属性条件,非常灵活。 - 能够访问嵌套层次结构,适合复杂的数据结构。
- 可以通过计算表达式找到特定位置的元素,比如索引。
CSS选择器():
- 基于标签名、类名、ID名和伪类等简单属性的选择,如
.myClass
和#myId
。 - 通过子元素关系(>、+、~)和通用选择器(*)进行组合选择。
- 有限的通配符,如
:hover
和:active
,用于表示状态变化时的样式。
总的来说,XPath更适用于复杂的文档结构和高级查找,而CSS选择器更适合常见的布局和样式控制。在Python中,它们通常与DOM解析库一起使用,如BeautifulSoup或lxml,来简化网页抓取和数据分析工作。