Scrapy是一个著名的爬虫框架,以前写爬虫都是用Python写那种特别原生低级的爬虫,一般都是以单线程为主,但是自己写多线程又会变的特别难,而且爬虫遇到突发状况就挂掉了。还有爬取某些网站,需要登录后才能抓取内容,所以涉及到模拟登录,总之感觉特别麻烦。虽然爬虫感觉很好玩,但是这一系列困难又成为了拦路虎!
Docker安装Scrapy
首先说一下Scrapy的安装吧,以前安装软件都会涉及好多依赖,往往安装这个软件,还得去下载别的依赖库,可能会遇到版本老啊,安装过程中报错啦,各种问题,总之,草泥马!所以在学习新技术的时候,并不是被这个新技术所难倒,而是首先软件的环境安装就被血虐!
前一段时间学了Docker,这个东西真是特别爽啊!所以今天我们用Docker来进行scrapy环境的搭建。在Docker hub上搜索Scrapy,看看有没有好人已经把镜像给我们做好了!找到一个还算合适的!
镜像名:aciobanu/scrapy
地址:https://hub.docker.com/r/aciobanu/scrapy/
把它拉取到本地仓库
docker pull aciobanu/scrapy
我们用pycharm来连接docker环境,也就是一旦我们的pycharm连接上选中的容器,那么我们在pycharm中写的代码使用的环境将是容器内的环境,而不是本机的环境。
我们的项目名字为tutorial,来连接一下docker
打开Project Interpreter -->右边⚙-->add remote -->选中Docker-->在下面的框中选择aciobanu/scrapy 这个镜像
连接docker现在环境已经搭建好了,屌不屌,真心很屌啊!用别人现成的镜像就好了!
本机安装方法(不用Docker)
https://www.jianshu.com/p/a03aab073a35
建立项目
标红的是我自己添加的,其他都是默认生成的!因为我本机也装了scrapy,所以直接用startproject命令建立的目录,如果仅仅用docker的话,目录需要自己手动建立!
项目目录Scrapy原理介绍
原理图Scrapy Engine
Scrapy的引擎,用来对这几个大的模块进行控制。
Scheduler调度器
主要维护url队列。
Downloader下载器
主要负责获取页面数据。
Spiders爬虫
这个是我们来操作的,我们可以创建一个爬虫用于抓取某一类网站,可以设置爬虫的爬取策略等。
Item Pipeline
用来对获取的数据进行处理,比如把数据存放到数据库啊,或者直接用文件来存储啊。
实战Scrapy框架
原理再好不如拉出来溜溜!用一个实例来练习一下!
我们来抓取博客园上的一些文章列表吧,来个简单易学的!
博客园地址
https://www.cnblogs.com/cate/mysql/1
我们看到这个页面上有好多文章,每一个文章卡片显示该文章的标题,发布时间,摘要,阅读量。每一页都有20个这样的文章卡片。直到我抓取的时候,mysql系列文章有120页,而且每页对应的链接都是有规律的,https://www.cnblogs.com/cate/mysql/1这是第一页链接,https://www.cnblogs.com/cate/mysql/2这是第二页链接。
我们最终想得到的数据是这样的,把每个文章的标题,阅读量,发布时间,摘要全部抓取下来,存储到项目根目录下的data.list文件中。
结果数据开始写代码吧!
在spiders目录下新建一个xiaohuar_spider.py的文件,代码如下:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import scrapy
import sys
reload(sys)
sys.setdefaultencoding("utf8")
class XiaoHuarSpider(scrapy.spiders.Spider):
# 爬虫的名字,这个是必须有的,而且name变量名是框架规定好的
name = "cnblogs_mysql"
page_index = 1 # 标记第几页
# url种子列表,这里我们以第一页为起始页面进行抓取,变量名为框架规定的,必须有,不可更改
start_urls = ['https://www.cnblogs.com/cate/mysql/' + str( page_index )]
# parse函数为框架默认函数,名称必须一样
def parse(self, response):
# 利用xpath方式来定位网页元素,写过爬虫的都懂得
post_items = response.xpath("//div[@id='wrapper']/div[@id='main']/div[@id='post_list']/div[@class='post_item']/div[@class='post_item_body']")
# 把每页的20个文章卡片信息通过yield方式存储起来
for post_items_body in post_items:
yield {
'article_title':
post_items_body.xpath("h3/a/text()").extract_first().strip(),
'article_summary':
# post_items_body.xpath("p[@class='post_item_summary']/text()").extract_first().strip(),
post_items_body.xpath("p[@class='post_item_summary']/text()").extract()[1].strip(),
'article_date':
post_items_body.xpath("div[@class='post_item_foot']/text()").extract()[1].strip(),
'article_view':
post_items_body.xpath("div[@class='post_item_foot']/span[@class='article_view']/a/text()").extract_first().strip()
}
next_page_url = None
# 标记当前是第几页
self.page_index += 1 # 抓取完当前页就加1
# 暴力些,我们把120页全抓了
if self.page_index <= 120:
# 拼接生成下一个抓取url
next_page_url = "https://www.cnblogs.com/cate/mysql/" + str(self.page_index)
else:
next_page_url = None
if next_page_url is not None:
# 将下一个待抓取的url加入url队列,后续继续进行抓取
yield scrapy.Request(response.urljoin(next_page_url))
然后把数据存储起来,打开pipelines.py文件,代码如下:
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
class TutorialPipeline(object):
# 默认函数,在爬虫启动的时候,创建data.list文件,设置为写权限
def open_spider(self, spider):
self.fp = open("data.list", "w")
# 默认函数,在爬虫关闭的时候,把文件流关闭
def close_spider(self, spider):
self.fp.close()
# 默认函数,用来把刚才yield存储的信息持久化到data.list中
def process_item(self, item, spider):
self.fp.write(item["article_title"] + "\n")
self.fp.write(item["article_view"] + "\n")
self.fp.write(item["article_date"] + "\n")
self.fp.write(item["article_summary"] + "\n\n")
return item
设置settings.py,代码如下:
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'tutorial.pipelines.TutorialPipeline': 300,
}
其实现在代码已经写完了,是不是看起来很爽啊,非常模块化!
正常启动Scrapy,直接在命令行终端用scrapy crawl 爬虫名
就可以启动,但是由于我们的scrapy环境处于docker中,而本机没有scrapy环境,所以直接在命令行运行命令,是缺少环境的。所以我们写个python脚本利用docker内的环境执行,从而来启动爬虫。
在项目根目录下新建begin.py,代码如下:
from scrapy import cmdline
cmdline.execute("scrapy crawl cnblogs_mysql".split())
新建Python应用
启动脚本在右上角点击下拉框,在弹出的对话框里,选择左上角➕号,选择Python,右侧给应用起名为spider,脚本路径为begin.py的路径,然后ok。
直接运行spider应用就可以通过begin.py脚本把Scrapy爬虫启动起来!
启动爬虫爬呀爬,爬呀爬。。。然后你会在根目录下发现多了一个data.list,打开之后的数据和上面演示的一样!
网友评论