1. 程式人生 > >[Python爬蟲] scrapy爬蟲系列 .安裝及入門介紹

[Python爬蟲] scrapy爬蟲系列 .安裝及入門介紹

        前面介紹了很多Selenium基於自動測試的Python爬蟲程式,主要利用它的xpath語句,通過分析網頁DOM樹結構進行爬取內容,同時可以結合Phantomjs模擬瀏覽器進行滑鼠或鍵盤操作。但是,更為廣泛使用的Python爬蟲框架是——Scrapy爬蟲。這是一篇在Windows系統下介紹 Scrapy爬蟲安裝及入門介紹的相關文章。

一. 安裝過程

        本文主要講述Windows下的安裝過程,首先我的Python是2.7.8版本。
        主要通過Python的PIP語句進行安裝:

pip install scrapy

        然後,輸入 pip install scrapy 
命令進行安裝。


        安裝成功後,通過cmd呼叫 scrapy 指令檢視,表示安裝成功。

 


        此時,scrapy安裝成功,可以進行第二步"第一個scrapy爬蟲實現"了~

正如xifeijian大神所說:“作為Python愛好者,如果不知道easy_install或者pip中的任何一個的話,那麼......”。easy_insall的作用和perl中的cpan,ruby中的gem類似,都提供了線上一鍵安裝模組的傻瓜方便方式,而pip是easy_install的改進版,提供更好的提示資訊,刪除package等功能。老版本的python中只有easy_install,沒有pip。常見的具體用法如下:

easy_install的用法:    
1) 安裝一個包    
 $ easy_install <package_name>    
 $ easy_install "<package_name>==<version>"    
2) 升級一個包    
 $ easy_install -U "<package_name>>=<version>"    
    
pip的用法    
1) 安裝一個包    
 $ pip install <package_name>    
 $ pip install <package_name>==<version>    
2) 升級一個包 (如果不提供version號,升級到最新版本)    
 $ pip install --upgrade <package_name>>=<version>    
3)刪除一個包    
 $ pip uninstall <package_name> 

二. 第一個scrapy爬蟲程式實現

        官網介紹:
        Scrapy是一個為了爬取網站資料,提取結構性資料而編寫的應用框架。可以應用在包括資料探勘,資訊處理或儲存歷史資料等一系列的程式中。其最初是為了 頁面抓取 (更確切來說, 網路抓取 )所設計的, 也可以應用在獲取API所返回的資料(例如 Amazon Associates Web Services ) 或者通用的網路爬蟲。
        An open source and collaborative framework for extracting the data you need from websites. In a fast, simple, yet extensible way.
        下面是參考官網在windows下實現的第一個scrapy爬蟲程式:


        開啟Python IDLE,建立myspider.py檔案,程式碼如下:
import scrapy

class BlogSpider(scrapy.Spider):
    name = 'blogspider'
    start_urls = ['http://blog.scrapinghub.com']

    def parse(self, response):
        for url in response.css('ul li a::attr("href")').re(r'.*/\d\d\d\d/\d\d/$'):
            yield scrapy.Request(response.urljoin(url), self.parse_titles)

    def parse_titles(self, response):
        for post_title in response.css('div.entries > ul > li a::text').extract():
            yield {'title': post_title}
        如果此時你試圖點選Run執行程式或在IDLE中輸入 scrapy runspider myspider.py,似乎返回如下錯誤:


        此時我懷疑Windows下需要呼叫cmd執行程式,還是強烈推薦在Linux下學習使用Python相關程式設計知識。呼叫cd去到檔案所在目錄:
        
cd G:\software\Program software\Python\python insert\scrapy project
        然後在執行程式,結果輸出如下所示:


        此時,程式能夠執行成功了,不論結果如何、程式碼如何,總算在Windows下跑起來了。下面第三部分,我再簡單介紹如何呼叫Scrapy爬蟲進行一個入門相關的爬取~

三. Scrapy入門介紹


        Windows下Ctrl+R呼叫CMD命令列。輸入命令如下:
1.chcp 936
unknown encoding: cp65001異常時,需要將編碼(UTF-8)修改為 簡體中文(GBK)

2.cd G:\software\Program software\Python\python insert\scrapy project
去到安裝Scrapy目錄下

3.cd scrapy-itzhaopin-master\itzhaopin
再次去到下載的檔案itzhaopin目錄下

4.scrapy crawl tencent
執行程式碼啟動這個Spider,進行下載
        最後執行會在scrapy-itzhaopin-master\itzhaopin資料夾下生產一個tencent.json的結果。資料量很大,下圖只展示部分日期是2015-11-07的資料,如下所示:





        其中程式碼itzhaopin專案的結果圖如下所示:參考原文作者部落格

├── itzhaopin
│   ├── itzhaopin
│   │   ├── __init__.py
│   │   ├── items.py
│   │   ├── pipelines.py
│   │   ├── settings.py
│   │   └── spiders
│   │      └── __init__.py
│   └── scrapy.cfg

scrapy.cfg: 專案配置檔案
items.py: 需要提取的資料結構定義檔案
pipelines.py:管道定義,用來對items裡面提取的資料做進一步處理,如儲存等
settings.py: 爬蟲配置檔案
spiders: 放置spider的目錄
        核心的幾個py檔案內容如下,詳見github:
        1.items.py:定義我們要抓取的資料
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

from scrapy.item import Item, Field  
class TencentItem(Item):  
    name = Field()                # 職位名稱  
    catalog = Field()             # 職位類別  
    workLocation = Field()        # 工作地點  
    recruitNumber = Field()       # 招聘人數  
    detailLink = Field()          # 職位詳情頁連結  
    publishTime = Field()         # 釋出時間  
        2.spiders資料夾中tencent_spider.py檔案:實現Spider
Spider是一個繼承自scrapy.contrib.spiders.CrawlSpider的Python類,有三個必需的定義的成員
        name: 名字,這個spider的標識
        start_urls:一個url列表,spider從這些網頁開始抓取
        parse():一個方法,當start_urls裡面的網頁抓取下來之後需要呼叫這個方法解析網頁內容,同時需要返回下一個需要抓取的網頁,或者返回items列表
import re
import json

from scrapy.selector import Selector
try:
    from scrapy.spider import Spider
except:
    from scrapy.spider import BaseSpider as Spider
from scrapy.utils.response import get_base_url
from scrapy.utils.url import urljoin_rfc
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor as sle


from itzhaopin.items import *
from itzhaopin.misc.log import *


class TencentSpider(CrawlSpider):
    name = "tencent"
    allowed_domains = ["tencent.com"]
    start_urls = [
        "http://hr.tencent.com/position.php"
    ]
    rules = [
        Rule(sle(allow=("/position.php\?&start=\d{,4}#a")), follow=True, callback='parse_item')
    ]

    def parse_item(self, response):
        items = []
        sel = Selector(response)
        base_url = get_base_url(response)
        sites_even = sel.css('table.tablelist tr.even')
        for site in sites_even:
            item = TencentItem()
            item['name'] = site.css('.l.square a').xpath('text()').extract()[0]
            relative_url = site.css('.l.square a').xpath('@href').extract()[0]
            item['detailLink'] = urljoin_rfc(base_url, relative_url)
            item['catalog'] = site.css('tr > td:nth-child(2)::text').extract()[0]
            item['workLocation'] = site.css('tr > td:nth-child(4)::text').extract()[0]
            item['recruitNumber'] = site.css('tr > td:nth-child(3)::text').extract()[0]
            item['publishTime'] = site.css('tr > td:nth-child(5)::text').extract()[0]
            items.append(item)
            #print repr(item).decode("unicode-escape") + '\n'

        sites_odd = sel.css('table.tablelist tr.odd')
        for site in sites_odd:
            item = TencentItem()
            item['name'] = site.css('.l.square a').xpath('text()').extract()[0]
            relative_url = site.css('.l.square a').xpath('@href').extract()[0]
            item['detailLink'] = urljoin_rfc(base_url, relative_url)
            item['catalog'] = site.css('tr > td:nth-child(2)::text').extract()[0]
            item['workLocation'] = site.css('tr > td:nth-child(4)::text').extract()[0]
            item['recruitNumber'] = site.css('tr > td:nth-child(3)::text').extract()[0]
            item['publishTime'] = site.css('tr > td:nth-child(5)::text').extract()[0]
            items.append(item)
            #print repr(item).decode("unicode-escape") + '\n'

        info('parsed ' + str(response))
        return items


    def _process_request(self, request):
        info('process ' + str(request))
        return request
       3.pipelines.py:實現PipeLine
PipeLine用來對Spider返回的Item列表進行儲存操作,可以寫入到檔案、或者資料庫等。PipeLine只有一個需要實現的方法:process_item,例如我們將Item儲存到JSON格式檔案中:
# 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

from scrapy import signals
import json
import codecs

class JsonWithEncodingTencentPipeline(object):

    def __init__(self):
        self.file = codecs.open('tencent.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(
)
        4.settings.py:設定檔案
# Scrapy settings for itzhaopin project
#
# For simplicity, this file contains only the most important settings by
# default. All the other settings are documented here:
#
#     http://doc.scrapy.org/en/latest/topics/settings.html
#

BOT_NAME = 'itzhaopin'

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

# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'itzhaopin (+http://www.yourdomain.com)'

ITEM_PIPELINES = {
    'itzhaopin.pipelines.JsonWithEncodingTencentPipeline': 300,
}

LOG_LEVEL = 'INFO'