尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

python--爬虫--成熟的爬虫框架Scrapy

python--爬虫--成熟的爬虫框架Scrapy 一、为什么要用Scrapy在大数据时代数据就是企业的核心资产。而获取外部数据最直接的方式之一就是爬虫。目前主流的爬虫技术有很多基于C的Larbin、基于Java的Webmagic和Nutch、基于Golang的Pholcus以及今天要重点介绍的——基于Python的Scrapy。那么问题来了为什么选Scrapy简单来说Scrapy是一个为了爬取网站数据、提取结构性数据而编写的应用框架可以应用在数据挖掘、信息处理或存储历史数据等一系列场景中。它底层基于Twisted异步网络框架并发能力非常强悍。举个直观的例子假设目标网站每页有500个条目Scrapy可以同时发起20个请求每个请求耗时1秒那么每秒就能拿到10000个条目。如果要将这些数据存储到云端每个存储操作耗时3秒就需要同时处理30000个写入请求。传统的多线程方案需要创建30000个线程系统根本无法承载但Scrapy基于异步机制只要硬件够30000个并发轻松搞定。这就是Scrapy最核心的竞争力——高吞吐量。二、Scrapy能做什么有了这个利器你可以做的事情太多了舆情监测获取互联网数据监测舆论动向评估事态发展热点发现监测新闻的转发、评论增量趋势发现潜在热点金融分析抓取大V调仓记录、上市公司年报辅助投资决策房产分析获取交易、价格数据分析市场走势关于反爬虫大部分情况下反爬虫需求不会影响到网站的正常使用。爬虫可以伪装成正常用户只是增加了一些代价而已。只要人能正常访问的网页爬虫在具备同等资源下就一定能抓取。三、Scrapy架构概览Scrapy采用组件化设计各模块间松耦合便于扩展和定制。┌─────────────────────────────────────────────────────┐ │ Scrapy Engine │ │ (引擎) │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │Scheduler │ │Downloader│ │ Spiders │ │ │ │ (调度器) │ │ (下载器) │ │ (爬虫) │ │ │ └──────────┘ └──────────┘ └──────────────┘ │ │ ↑ ↑ ↑ │ │ ┌──────────────────────────────────────────┐ │ │ │ Item Pipeline (项目管道) │ │ │ │ (数据清洗、验证、存储) │ │ │ └──────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘核心组件说明组件职责Engine引擎控制所有组件间的数据流触发事件Scheduler调度器接收请求并排队去重按需返回给引擎Downloader下载器下载网页内容返回响应Spiders爬虫用户编写的解析逻辑提取数据和新的URLItem Pipeline管道数据处理清洗、验证、存数据库Middlewares中间件处理请求/响应的钩子可扩展代理、UA等数据流转过程引擎从Spider获取初始请求引擎将请求交给调度器排队调度器返回下一个请求给引擎引擎通过下载器中间件把请求发给下载器下载器完成下载返回响应给引擎引擎通过爬虫中间件把响应发给Spider处理Spider解析响应产出Item和新的Request引擎把Item交给Pipeline处理把新Request交给调度器重复上述过程直到没有更多请求四、快速上手4.1 安装pipinstallscrapy# 或使用国内镜像加速pipinstallscrapy-ihttps://pypi.douban.com/simple# 验证安装scrapy versionWindows用户注意可能需要先安装Microsoft Visual C Build Tools来解决依赖包编译问题。4.2 创建项目scrapy startproject tutorial生成的项目结构tutorial/ scrapy.cfg # 部署配置文件 tutorial/ __init__.py items.py # 数据模型定义 pipelines.py # 数据处理管道 settings.py # 项目配置 spiders/ # 爬虫目录 __init__.py4.3 编写第一个爬虫在spiders/quotes_spider.py中创建爬虫类importscrapyclassQuotesSpider(scrapy.Spider):namequotes# 爬虫唯一标识defstart_requests(self):urls[http://quotes.toscrape.com/page/1/,http://quotes.toscrape.com/page/2/,]forurlinurls:yieldscrapy.Request(urlurl,callbackself.parse)defparse(self,response):pageresponse.url.split(/)[-2]filenamefquotes-{page}.htmlwithopen(filename,wb)asf:f.write(response.body)self.log(fSaved file{filename})4.4 运行爬虫# 进入项目根目录cdtutorial# 执行爬虫scrapy crawl quotes执行后你会看到生成了quotes-1.html和quotes-2.html两个文件。五、数据提取选择器Scrapy提供了两种强大的数据提取方式CSS选择器和XPath。5.1 交互式Shell调试先用Shell测试选择器是否正确scrapy shellhttp://quotes.toscrape.com/page/1/5.2 CSS选择器示例# 提取标题response.css(title::text).get()# Quotes to Scrape# 提取单个元素response.css(span.text::text).get()# 提取多个元素response.css(div.tags a.tag::text).getall()# 提取属性response.css(li.next a::attr(href)).get()注意::text和::attr(name)是Scrapy扩展的伪元素标准CSS不支持但爬虫场景非常实用。5.3 XPath选择器示例response.xpath(//title/text()).get()response.xpath(//div[classquote]/span/text()).getall()response.xpath(//a/href).getall()XPath功能更强大可以基于内容进行选择推荐深入学习。六、完整示例爬取名言网站6.1 定义数据结构items.pyimportscrapyclassQuoteItem(scrapy.Item):textscrapy.Field()# 名言内容authorscrapy.Field()# 作者tagsscrapy.Field()# 标签列表6.2 编写爬虫spiders/quotes_spider.pyimportscrapyclassQuotesSpider(scrapy.Spider):namequotesstart_urls[http://quotes.toscrape.com/page/1/]defparse(self,response):forquoteinresponse.css(div.quote):yield{text:quote.css(span.text::text).get(),author:quote.css(small.author::text).get(),tags:quote.css(div.tags a.tag::text).getall(),}# 翻页处理next_pageresponse.css(li.next a::attr(href)).get()ifnext_page:yieldscrapy.Request(response.urljoin(next_page),callbackself.parse)6.3 数据存储方式一直接导出最简单scrapy crawl quotes-oquotes.json# 或导出为JSON Lines格式scrapy crawl quotes-oquotes.jl注意Scrapy默认会追加到已有文件而非覆盖重复运行会生成损坏的JSON文件。建议使用.jl格式每行一个JSON对象。方式二自定义Pipeline更灵活在pipelines.py中实现数据清洗和存储importjsonfromitemadapterimportItemAdapterclassJsonWriterPipeline:defopen_spider(self,spider):self.fileopen(items.jsonl,w)defclose_spider(self,spider):self.file.close()defprocess_item(self,item,spider):linejson.dumps(ItemAdapter(item).asdict())\nself.file.write(line)returnitem然后在settings.py中启用管道ITEM_PIPELINES{myproject.pipelines.JsonWriterPipeline:300,}数值300决定了执行顺序数字越小越先执行通常定义在0-1000范围。七、进阶技巧7.1 爬虫参数通过-a传递参数给爬虫scrapy crawl quotes-ataghumor在爬虫中通过self.tag获取defstart_requests(self):urlhttp://quotes.toscrape.com/taggetattr(self,tag,None)iftag:urlf{url}tag/{tag}yieldscrapy.Request(url,self.parse)7.2 关键配置settings.py# 禁用robots.txt需谨慎ROBOTSTXT_OBEYFalse# 请求间隔防封DOWNLOAD_DELAY2# 伪装User-AgentUSER_AGENTMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36# 自动限速AUTOTHROTTLE_ENABLEDTrue# 并发控制CONCURRENT_REQUESTS32CONCURRENT_REQUESTS_PER_DOMAIN87.3 遇到动态加载内容怎么办对于JavaScript渲染的页面可以结合Splash或Selenium。以Splash为例pipinstallscrapy-splash配置中间件使用Splash渲染SPLASH_URLhttp://localhost:8050DOWNLOADER_MIDDLEWARES{scrapy_splash.SplashCookiesMiddleware:723,scrapy_splash.SplashMiddleware:725,}八、总结Scrapy的核心优势在于高性能基于Twisted异步框架并发能力强模块化组件松耦合便于扩展开箱即用内置选择器、中间件、导出等功能社区活跃遇到问题容易找到解决方案记住只要人能访问的网页爬虫在同等资源下就一定能抓取。
返回列表