scrapy 实战(一)如何构建一个爬虫系统

2017-01-17

如何构建一个爬虫系统?

pip install scrapy
scrapy startproject examplespider
cd /path/to/examplespider/
scrapy crawl <http://example.com/>

对就这样完事了。一个基础的爬虫系统已经构建了。

然而,这远远是不够的。

比如: js生成的页面,抓页面图片,html解析,重复性检查,等等。

接下来,以抓取 www.guoku.com 为例构建一个 scrapy 项目

scrapy startproject andromeda
  • 看下目录结构:
    
    ├── andromeda
    │   ├── __init__.py
    │   ├── __init__.pyc
    │   ├── items.py
    │   ├── middlewares    
    │   │   ├── __init__.py
    │   │   └── downloader.py  #增加下载器中间件
    │   ├── pipelines.py
    │   ├── settings.py
    │   ├── settings.pyc
    │   └── spiders
    │       ├── __init__.py
    │       └── guoku.py    # 增加了抓取 guoku.py 
    └── scrapy.cfg  

这里主要说明两个文件:

guoku.py
items.py

首先 item.py

# -*- coding: utf-8 -*-  
  
import scrapy  
  
  
class EntityItem(scrapy.Item):  
    brand   = scrapy.Field()  
    title   = scrapy.Field()
    price = scrapy.Field()

这里构建了一个 EntityItem 类。把我们需要的 数据建立一个类

这里包含了,

商品的品牌,名称,价格,等信息。图片下期再说。

再次是 guoku.py

定义完数据结构,我们就可以实施抓取了。

# coding=utf-8  
import scrapy  
from urlparse import urlparse  
from andromeda.items import EntityItem  
  
  
  
class GKSpider(scrapy.Spider):    #定义一个爬虫类  
  
    name    = "guoku"             #定义爬虫名字  
    allowed_domains = [  
        'guoku.com',  
    ]  
  
  
    def __init__(self, *args, **kwargs):  
        super(GKSpider, self).__init__(*args, **kwargs)  
        self.start_urls = [  
                "<https://www.guoku.com/selected>/", #定义需要抓取URL  
        ]  
  
    def parse(self, response):  
        o = urlparse(response.url)  
        urls    = response.css('a.img-entity-link::attr(href)').extract()  
        for uri in urls:  
            url = "{scheme}://{host}{uri}".format(scheme=o.scheme,  
                                                    host=o.netloc,  
                                                    uri=uri)  
            yield scrapy.Request(url, self.pares_entity)  
  
    def pares_entity(self, response):  
        self.logger.info(response.url)  
  
        item            = EntityItem()  
        item['brand']   = response.css('div.brand::text').extract_first()  
        item['title']   = response.css('div.entity-title::text').extract_first()  
        item['price']   = response.css('div.price-tag > span::text').extract_first()  
        return item

start_urls 定义我们需要抓取的链接

def __init__(self, uri, *args, **kwargs):  
    super(GKSpider, self).__init__(*args, **kwargs)  
    self.start_urls = [  
            "https://www.guoku.com/{uri}/".format(uri=uri),
    ]  

解析列表页

def parse(self, response):  
    o = urlparse(response.url)
    #这里主要解析出列表页中的单页的 URL  
    urls    = response.css('a.img-entity-link::attr(href)').extract()
  
    for uri in urls:
        #通过 for 循环将单页的URL压入堆栈   
        url = "{scheme}://{host}{uri}".format(scheme=o.scheme,  
                                                host=o.netloc,  
                                                uri=uri)
        yield scrapy.Request(url, self.pares_entity)

解析单页

def pares_entity(self, response):  
    self.logger.info(response.url)  

    #实例化 EntityItem 类。 通过解析器获取 html 中我们所需要的信息  
    item            = EntityItem()  
    item['brand']   = response.css('div.brand::text').extract_first()  
    item['title']   = response.css('div.entity-title::text').extract_first()  
    item['price']   = response.css('div.price-tag > span::text').extract_first()
    return item

项目源代码