scrapy爬蟲框架實例二


  本實例主要通過抓取慕課網的課程信息來展示scrapy框架抓取數據的過程。

 1、抓取網站情況介紹

  抓取網站:http://www.imooc.com/course/list 

  抓取內容:要抓取的內容是全部的課程名稱,課程簡介,課程URL ,課程圖片URL,課程人數(由於動態渲染暫時沒有獲取到)

  網站圖片:

  

  

  

  2、建立工程

  在命令行模式建立工程

  scrapy startproject scrapy_course

  建立完成后,用pycharm打開,目錄如下:

  

  scrapy.cfg: 項目的配置文件

  scrapytest/: 該項目的python模塊。之后您將在此加入代碼。

  scrapytest/items.py: 項目中的item文件.

  scrapytest/pipelines.py: 項目中的pipelines文件.

  scrapytest/settings.py: 項目的設置文件.

  scrapytest/spiders/: 放置spider代碼的目錄.

  

 3、創建一個爬蟲

  下面按步驟講解如何編寫一個簡單的爬蟲。

  我們要編寫爬蟲,首先是創建一個Spider

  我們在scrapy_course/spiders/目錄下創建一個文件MySpider.py

  文件包含一個MySpider類,它必須繼承scrapy.Spider類。

  同時它必須定義一下三個屬性:

  -name: 用於區別Spider。 該名字必須是唯一的,您不可以為不同的Spider設定相同的名字。 

  -start_urls: 包含了Spider在啟動時進行爬取的url列表。 因此,第一個被獲取到的頁面將是其中之一。 后續的URL則從初始的URL獲取到的數據中提取。 

  -parse() 是spider的一個方法。 被調用時,每個初始URL完成下載后生成的 Response 對象將會作為唯一的參數傳遞給該函數。 該方法負責解析返回的數據(response data),提取數據(生成item)以及生成需要進一步處理的URL的 Request 對象。

 

  創建完成后MySpider.py的代碼如下

  

 

  定義爬蟲項目

  創建完了Spider文件,先不急着編寫爬取代碼 

  我們先定義一個容器保存要爬取的數據。

  這樣我們就用到了Item 

  為了定義常用的輸出數據,Scrapy提供了Item類。Item對象是種簡單的容器,保存了爬取到得數據。 其提供了 類似於詞典(dictionary-like)的API以及用於聲明可用字段的簡單語法。

  我們在工程目錄下可以看到一個items文件,我們可以更改這個文件或者創建一個新的文件來定義我們的item。

  這里,我們在同一層創建一個新的item文件CourseItems.py

  

  根據如上的代碼,我們創建了一個名為courseItem的容器,用來保存、抓取的信息, 

  title->課程標題, url->課程url, image_url->課程標題圖片, introduction->課程描述, student->學習人數

  在創建完item文件后我們可以通過類似於詞典(dictionary-like)的API以及用於聲明可用字段的簡單語法。

  常用方法如下

    

 4、編寫Spider代碼

  定義了item后我們就能進行爬取部分的工作了。

  為了簡單清晰,我們先抓取一個頁面中的信息。

  首先我們編寫爬取代碼

  我們在上文說過,爬取的部分在MySpider類的parse()方法中進行。 

  parse()方法負責處理response並返回處理的數據以及(/或)跟進的URL。 

  該方法及其他的Request回調函數必須返回一個包含 Request 及(或) Item 的可迭代的對象。

  我們在之前創建的MySpider.py中編寫如下代碼。 

  注意和上邊MySpider.py的區別

   

# -*- coding:utf8-*-
import scrapy
import sys
import time
reload(sys)
sys.setdefaultencoding('utf-8')
from scrapy_course.items import  CourseItem
from scrapy.selector import Selector
sys.stdout = open('output.txt', 'w')
pageIndex = 0

class MySpider(scrapy.Spider):

    #用於區別Spider
    name = "MySpider"
    #允許訪問的域
    allowed_domains = ['imooc.com']
    #爬取的地址
    start_urls = ["http://www.imooc.com/course/list"]
    #爬取方法
    def parse(self, response):

        # 實例一個容器保存爬取的信息
        item = CourseItem()
        # 這部分是爬取部分,使用xpath的方式選擇信息,具體方法根據網頁結構而定
        # 先獲取每個課程的div
        sel = Selector(response)
        title = sel.xpath('/html/head/title/text()').extract()  # 標題
        print title[0]
        # sels = sel.xpath('//div[@class="course-card-content"]')
        sels = sel.xpath('//a[@class="course-card"]')
        pictures = sel.xpath('//div[@class="course-card-bk"]')
        index = 0
        global pageIndex
        pageIndex += 1
        print u'%s' % (time.strftime('%Y-%m-%d %H-%M-%S'))
        print '' + str(pageIndex)+ ''
        print '----------------------------------------------'
        for box in sels:
            print ' '
            # 獲取div中的課程標題
            item['title'] = box.xpath('.//h3[@class="course-card-name"]/text()').extract()[0].strip()
            print '標題:' + item['title']

            # 獲取div中的課程簡介
            item['introduction'] = box.xpath('.//p/text()').extract()[0].strip()
            print '簡介:' + item['introduction']

            # 獲取每個div中的課程路徑
            item['url'] = 'http://www.imooc.com' + box.xpath('.//@href').extract()[0]
            print  '路徑:' +item['url']

            # 獲取div中的學生人數
            item['student'] = box.xpath('.//div[@class="course-card-info"]/text()').extract()[0].strip()
            print item['student']

            # 獲取div中的標題圖片地址
            item['image_url'] = pictures[index].xpath('.//img/@src').extract()[0]
            print '圖片地址:' + item['image_url']
            index += 1
            yield item

        time.sleep(1)
        print u'%s' % (time.strftime('%Y-%m-%d %H-%M-%S'))
        # next =u'下一頁'
        # url = response.xpath("//a[contains(text(),'" + next + "')]/@href").extract()
        # if url:
        #     # 將信息組合成下一頁的url
        #     page = 'http://www.imooc.com' + url[0]
        #     # 返回url
        #     yield scrapy.Request(page, callback=self.parse)

  使用Pipeline處理數據

  當我們成功獲取信息后,要進行信息的驗證、儲存等工作,這里以儲存為例。 

  當Item在Spider中被收集之后,它將會被傳遞到Pipeline,一些組件會按照一定的順序執行對Item的處理。 

  Pipeline經常進行一下一些操作: 

  清理HTML數據 

  驗證爬取的數據(檢查item包含某些字段) 

  查重(並丟棄) 

  目前暫時將爬取結果保存到文本中

  這里只進行簡單的將數據儲存在json文件的操作。

  pipelines.py代碼如下

 
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import codecs
import json

class ScrapyCoursePipeline(object):
    def __init__(self):
        # self.file = open('data.json', 'wb')
        # self.file = codecs.open(
        #     'spider.txt', 'w', encoding='utf-8')
        self.file = codecs.open(
            'spider.json', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        line = json.dumps(dict(item), ensure_ascii=False) + "\n"
        self.file.write(line)
        return item

    def spider_closed(self, spider):
        self.file.close()

  要使用Pipeline,首先要注冊Pipeline

  找到settings.py文件,這個文件時爬蟲的配置文件

  在其中添加

  

ITEM_PIPELINES = {
        'scrapy_course.pipelines.ScrapyCoursePipeline':300
        }

 

  上面的代碼用於注冊Pipeline,其中scrapy_course.pipelines.ScrapyCoursePipeline為你要注冊的類,右側的’300’為該Pipeline的優先級,范圍1~1000,越小越先執行。

  進行完以上操作,我們的一個最基本的爬取操作就完成了

  這時我們再運行

  5、運行

  在命令行下運行scrapy crawl MySpider

  

  

  

  如何要把數據存儲到文本文件中,在代碼前面增加以后代碼,

  sys.stdout = open('output.txt', 'w'),這樣就會把數據保存到當前項目路徑下的output.txt文件里面

  如下:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM