從零開始寫爬蟲

幾個朋友對爬蟲很感興趣,他們也都是開發人員,一個PHP開發兩個JAVA開發,都沒有過python項目開發經驗,正好其中一個最近要爬一個網店的產品信息,因此但願我能拿這網站當demo寫一個爬蟲來給他們參考學習。要爬取的頁是http://list.secoo.com/watches...,只要爬取產品相關了屬性就能夠。css

clipboard.png
這就是要爬取的相關信息html

爬蟲框架使用的是python的scrapy,這也是我如今項目中使用的爬蟲框架。朋友們因爲沒有使用過scrapy,所以推薦他們去看一下框架文檔,http://scrapy-chs.readthedocs...,這是scrapy的入門教程,基本上看完前面幾章就能快速開發一個簡單的爬蟲了。python

1、生成代碼
scrapy提供了命令行工具來快速生成一個簡單的爬蟲,咱們也使用這個工具來快速生成代碼。在終端下面運行下面的命令就能快速生成一個scrapy爬蟲的基礎框架,免去一些最原始的代碼開發操做。mysql

scrapy startproject secoo

clipboard.png

生成的項目文件就是上面的樣子,spiders目錄是存放爬蟲代碼,items.py是定義爬蟲要爬取的字段信息,pipelines.py是用來處理爬蟲爬到的數據的,好比用來作保存操做,像是存redis或是mysql等等,settings.py是項目的基礎配置文件,定義一些爬蟲的全局參數。
生成完項目基礎代碼後還能夠使用下面的命令行工具來生成爬蟲代碼最簡單的代碼,和建立項目同樣,能夠省去建立文件的麻煩。redis

scrapy genspider watch secoo.com

命令執行完成後咱們就會在spiders目錄下發現咱們生成好的爬蟲文件watch.py了。咱們就在這個文件裏開發爬蟲的相關邏輯。sql

2、 定義爬蟲數據字段
爬蟲要爬頁面,確定是要從爬取到的頁面中提取到咱們想要的字段信息,這樣的話咱們就要先來定義一下哪些是咱們要的字段,後面好在本地保存,這個就是scrapy裏的items來負責的。
咱們打開根目錄下面的items.py文件,這個文件裏定義一個SecooItem的類,咱們定義了4個字段,分別用來保存產品名、路徑、價格和庫存信息,這一步操做咱們就完成了,後面的爬蟲按這個定義好的格式來保存數據就能夠了。數據庫

import scrapy

class SecooItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    product_name = scrapy.Field()       #產品名
    breadcrumb = scrapy.Field()         #麪包屑路徑
    product_price = scrapy.Field()      #產品價格
    product_stock = scrapy.Field()      #庫存狀態

3、定義保存數據操做
這一步是要來定義爬蟲的數據提取出來之後,按照items.py定義的格式格式化之後是如何保存的。因爲咱們是寫一個demo給你們來參考,所以這一部分代碼是沒有寫實際的數據保存操做的,咱們只定義了這個操做類,若是是想要進行保存數據操做的話能夠直接修改SecooPipeline類的process_item方法,在這裏能夠和正常腳本操做數據庫同樣進行鏈接、寫入操做的。json

class SecooPipeline(object):
    def process_item(self, item, spider):
        return item

4、頁面爬取
最後一步就是最重要的一步了,咱們要進行爬蟲邏輯的開發。在這裏先貼上代碼,而後再來解釋每一步的操做。框架

# -*- coding: utf-8 -*-
import scrapy
from secoo.items import SecooItem

class WatchSpider(scrapy.Spider):
    name = 'watch'
    allowed_domains = ['secoo.com']
    start_urls = ['http://list.secoo.com/watches/93-0-0-0-0-1-0-0-1-10-0-908_0.shtml']


    def parse(self, response):
        '''
        解析商品列表頁面的內容,提取商品頁面連接並生成請求
        :param response:
        :return:
        '''
        #解析商品連接
        goods_links = response.css('body .product_box .commodity-list dl .show_tips dt>a::attr(href)').extract()

        for url in goods_links:
            #分別去爬取商品信息
            yield scrapy.Request(url, callback=self.parse_goods, dont_filter=True)

        next_page = self.get_next_page_url(response)
        if next_page:
            yield scrapy.Request(next_page, callback=self.parse)


    def get_next_page_url(self, response):
        '''
        獲取下一個商品列表的連接
        :param response:
        :return:
        '''
        return response.css('a.next::attr(href)').extract_first()

    def parse_goods(self, response):
        '''
        解析商品內容,提取要爬取的字段
        :param response:
        :return:
        '''
        name = response.css('.sopdetailsCon .contents .info_r .proName h2::text').extract_first()
        price = response.css('#secooPriceJs::text').extract_first()
        stock = response.css('#youhuo::text').extract_first()
        breadcrumb = '->'.join(response.css('.smallNav p a::text').extract())

        yield SecooItem({
            'product_name': name,
            'breadcrumb': breadcrumb,
            'product_price': price,
            'product_stock': stock,
        })

在使用命令行工具生成爬蟲的時候就會幫咱們定義好三個變量,一個是name,這個是定義爬蟲的名稱的;第二個是allowed_domains,這個是一個list,定義爬蟲容許爬取的域名;最後一個start_urls變量也是一個list類型,是用來定義爬蟲入口URL的,能夠定義多個入口地址。
接下來是parse方法,這個方法是框架默認的第一個處理方法,用來解析網頁內容的。大概的邏輯在註釋中寫的比較清楚,邏輯就是咱們解析那個產品列表頁面,從其中提取產品列表連接,而後生成請求去爬取產品信息,而後再去提取產品列表頁面的下一頁連接,再生成請求去請求這個頁面,處理回調方法就是parse方法,這樣就能實現全部翻頁爬取。
在parse方法裏提取出來的產品連接生成了請求以後,我把爬蟲回調處理方法設置成parse_goods,所以咱們要去定義一個parse_goods方法來處理產品頁面html內容。經過xpath或是css的selector方法來提取咱們想要爬取的內容,而後丟給pipelines.py來處理了。這樣咱們就把爬蟲的全部邏輯實現完成了,最後一步不是驗證爬蟲的運行狀況了。dom

5、運行
最後一步就是就是運行操做,咱們在命令行下,進入項目目錄,而後執行下面命令就能正常運行爬蟲了,因爲咱們沒有寫保存操做,所以咱們就把數據導出到一個json文件裏。

scrapy crawl watch --output=product.json

clipboard.png

相關文章
相關標籤/搜索