您的位置:首页 > 数据库 > Mongodb

手把手教你scrapy + mongodb 爬虫爬取GooglePlay

2016-11-15 03:43 399 查看
这几天折腾了一个分布式爬虫,我自己也是刚开始学,查了很多资料,现在终于可以动了,我觉得应该发文纪念一下,也是一个总结.

scrapy是一个python的爬虫框架,可以让你很快的开发出一个爬虫,首先假定你已经安装了python, 你还需要安装一下scrapy,可以用pip来安装:

1. install Python-pip: sudo apt-get install python-pip

2. install scrapy: sudo pip install scrapy

OK, 我们现在就用scrapy来创建一个爬虫:

$ scrapy startproject myFirstCrawler

上面我们就创建了一个基本的爬虫结构,默认情况下是没有爬虫那个文件的,只有一些其他的配套的文件如下:

$ tree
.
├── myFirstCrawler
│   ├── __init__.py
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       └── __init__.py
└── scrapy.cfg

根据创建时的提示,我们可以让scrapy为我们提供一个模板spider:

$ cd myFirstCrawler

$ scrapy genspidermySpider example.com

下面我们就有了一个scrapy框架的完整结构

$ tree
.
├── myFirstCrawler
│   ├── __init__.py
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       ├── mySpider.py
│       └── __init__.py
└── scrapy.cfg



Scrapy主要包括了以下组件:

引擎(Scrapy): 用来处理整个系统的数据流处理, 触发事务(框架核心)
调度器(Scheduler): 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
下载器(Downloader): 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
爬虫(Spiders): 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
项目管道(Pipeline): 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
下载器中间件(Downloader Middlewares): 位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。
爬虫中间件(Spider Middlewares): 介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
调度中间件(Scheduler Middewares): 介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。
Scrapy运行流程大概如下:

首先,引擎从调度器中取出一个链接(URL)用于接下来的抓取
引擎把URL封装成一个请求(Request)传给下载器,下载器把资源下载下来,并封装成应答包(Response)
然后,爬虫解析Response
若是解析出实体(Item),则交给实体管道进行进一步的处理。
若是解析出的是链接(URL),则把URL交给Scheduler等待抓取
其中items.py中定义了你想要抓取的信息,例如:

# -*- coding: utf-8 -*-
import scrapy

class AppCrawlerItem(scrapy.Item):
Name = scrapy.Field()
URL = scrapy.Field()
Price = scrapy.Field()
Genre = scrapy.Field()
Downloads = scrapy.Field()
Rating = scrapy.Field()
Review_number = scrapy.Field()
Updated = scrapy.Field()
Author = scrapy.Field()
Version = scrapy.Field()

setting.py中定义了一些配置,包括指定pipeline,配置数据库信息,或者一些下载速率限制,log配置.例如:

BOT_NAME = 'AppCrawler'

SPIDER_MODULES = ['AppCrawler.spiders']
NEWSPIDER_MODULE = 'AppCrawler.spiders'

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

MONGODB_HOST= '127.0.0.1'
MONGODB_PORT = 27017
MONGODB_DBNAME= 'Jonah'
MONGODB_DOCNAME= 'Apps'

LOG_STDOUT = True
LOG_LEVEL = 'ERROR'
LOG_FILE = 'Apps.log'


在pipeline.py中会得到最终抓到的item,可以在这里将items存储到数据库中去.例如:

import pymongo

from scrapy.conf import settings

class AppcrawlerPipeline(object):
def __init__(self):
host = settings['MONGODB_HOST']
port = settings['MONGODB_PORT']
dbName = settings['MONGODB_DBNAME']
client = pymongo.MongoClient(host=host, port=port)
tdb = client[dbName]
self.post = tdb[settings['MONGODB_DOCNAME']]

def process_item(self, item, spider):
AppInfo = dict(item)
self.post.insert(AppInfo)
return item

还有最重要的就是myspider.py文件了,这是我们的爬虫文件,来看看长什么样:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from AppCrawler.items import AppCrawlerItem
from scrapy.spiders import Rule, CrawlSpider

class AppSpider(CrawlSpider):
name = "App"
allowed_domains = ["play.google.com"]
start_urls = [
'http://play.google.com/',
'https://play.google.com/store/apps/details?id=air.net.machinarium.Machinarium.GP'
]

rules =(
Rule(LinkExtractor(allow=("https://play\.google\.com/store/apps/details", )), callback = 'parse_item', follow = True),
)

def parse_item(self, response):
if response.url.find('reviewId') != -1: return;
item = AppCrawlerItem()

item["Name"] = response.xpath('//div[@class="id-app-title"]/text()').extract_first().strip()
item["URL"] = response.url[0]
item["Downloads"] = response.xpath("//div[@itemprop='numDownloads']/text()").extract_first().strip()
item["Updated"] = response.xpath("//div[@itemprop='datePublished']/text()").extract_first().strip()
item["Version"] = response.xpath('//div[@itemprop="softwareVersion"]/text()').extract_first().strip()
item["Review_number"] = response.xpath("//span[@class='reviews-num']/text()").extract_first().strip()
item["Rating"] = float(response.xpath("//div[@class='score']/text()").extract_first().strip())
item["Author"] = response.xpath('//div[@itemprop="author"]/a/span/text()').extract_first().strip()
item["Genre"] = response.xpath('//span[@itemprop="genre"]/text()').extract_first().strip()
price = response.xpath('//button[@class="price buy id-track-click id-track-impression"]/span[2]/text()').extract_first().strip()
if price == u'Install': item["Price"] = 0
else: item["Price"] =float(price.split()[0][1:])

yield item


现在爬虫已经准备好了,要将数据存储到mongodb中也很方便,首先安装mongodb和pymongo:

$ sudo apt-get install mongodb

$ sudo pip install pymongo

然后按照上面的setting.py和pipeline.py中配置即可完成整个工程.

你可以在github找到完整的项目:https://github.com/renmaoting/GooglePlayCrawler

参考:http://www.jianshu.com/p/078ad2067419
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scrapy 爬虫 mongodb