欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

實踐Python的爬蟲框架Scrapy來抓取豆瓣電影TOP250

 更新時間:2016年01月20日 11:53:22   作者:王宇昊  
這篇文章主要介紹了實踐Python的爬蟲框架Scrapy來抓取豆瓣電影TOP250的過程,文中的環(huán)境基于Windows操作系統(tǒng),需要的朋友可以參考下

安裝部署Scrapy

在安裝Scrapy前首先需要確定的是已經(jīng)安裝好了Python(目前Scrapy支持Python2.5,Python2.6和Python2.7)。官方文檔中介紹了三種方法進(jìn)行安裝,我采用的是使用 easy_install 進(jìn)行安裝,首先是下載Windows版本的setuptools(下載地址:http://pypi.python.org/pypi/setuptools),下載完后一路NEXT就可以了。
安裝完setuptool以后。執(zhí)行CMD,然后運行一下命令:

easy_install -U Scrapy

同樣的你可以選擇使用pip安裝,pip的地址:http://pypi.python.org/pypi/pip
使用pip安裝Scrapy的命令為

pip install Scrapy

如果你的電腦先前裝過visual studio 2008 或 visual studio 2010那么一起順利,Scrapy已經(jīng)安裝完成。如果出現(xiàn)下列報錯:Unable to find vcvarsall.bat 那么你需要折騰下。你可以安裝visual studio 后進(jìn)行安裝或采用下面的方式進(jìn)行解決:
首先安裝MinGW(MinGW下載地址:http://sourceforge.net/projects/mingw/files/),在MinGW的安裝目錄下找到bin的文件夾,找到mingw32-make.exe,復(fù)制一份更名為make.exe;
把MinGW的路徑添加到環(huán)境變量path中,比如我把MinGW安裝到D:\MinGW\中,就把D:\MinGW\bin添加到path中;
打開命令行窗口,在命令行窗口中進(jìn)入到要安裝代碼的目錄下;
輸入如下命令 setup.py install build –compiler=mingw32 就可以安裝了。

如果出現(xiàn)“xslt-config' 不是內(nèi)部或外部命令,也不是可運行的程序或批處理文件?!卞e誤,原因主要是lxml安裝不成功,只要上http://pypi.python.org/simple/lxml/下載個exe文件進(jìn)行安裝就可以了。
下面就可以進(jìn)入正題了。

新建工程
讓我們來用爬蟲獲取豆瓣電影Top 250的電影信息吧。開始之前,我們新建一個Scrapy工程。因為我用的Win7,所以在CMD中進(jìn)入一個我希望保存代碼的目錄,然后執(zhí)行:

D:\WEB\Python>scrapy startproject doubanmoive

這個命令會在當(dāng)前目錄下創(chuàng)建一個新的目錄doubanmoive,目錄結(jié)構(gòu)如下:

D:\WEB\Python\doubanmoive>tree /f
Folder PATH listing for volume Data
Volume serial number is 00000200 34EC:9CB9
D:.
│ scrapy.cfg
│
└─doubanmoive
 │ items.py
 │ pipelines.py
 │ settings.py
 │ __init__.py
 │
 └─spiders
   __init__.py

這些文件主要為:

  • doubanmoive/items.py: 定義需要獲取的內(nèi)容字段,類似于實體類。
  • doubanmoive/pipelines.py: 項目管道文件,用來處理Spider抓取的數(shù)據(jù)。
  • doubanmoive/settings.py: 項目配置文件
  • doubanmoive/spiders: 放置spider的目錄

定義項目(Item)

Item是用來裝載抓取數(shù)據(jù)的容器,和Java里的實體類(Entity)比較像,打開doubanmoive/items.py可以看到默認(rèn)創(chuàng)建了以下代碼。

from scrapy.item import Item, Field

class DoubanmoiveItem(Item):
  pass

我們只需要在 Doubanmoive 類中增加需要抓取的字段即可,如 name=Field() ,最后根據(jù)我們的需求完成代碼如下。

from scrapy.item import Item, Field

class DoubanmoiveItem(Item):
 name=Field()#電影名
 year=Field()#上映年份
 score=Field()#豆瓣分?jǐn)?shù)
 director=Field()#導(dǎo)演
 classification=Field()#分類
 actor=Field()#演員

編寫爬蟲(Spider)

Spider是整個項目中最核心的類,在這個類里我們會定義抓取對象(域名、URL)以及抓取規(guī)則。Scrapy官方文檔中的教程是基于 BaseSpider 的,但 BaseSpider 只能爬取給定的URL列表,無法根據(jù)一個初始的URL向外拓展。不過除了 BaseSpider ,還有很多可以直接繼承 Spider 的類,比如 scrapy.contrib.spiders.CrawlSpider 。

在 doubanmoive/spiders 目錄下新建moive_spider.py文件,并填寫代碼。

# -*- coding: utf-8 -*-
from scrapy.selector import Selector
from scrapy.contrib.spiders import CrawlSpider,Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from doubanmoive.items import DoubanmoiveItem

class MoiveSpider(CrawlSpider):
 name="doubanmoive"
 allowed_domains=["movie.douban.com"]
 start_urls=["http://movie.douban.com/top250"]
 rules=[
  Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/top250\?start=\d+.*'))),
  Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/subject/\d+')),callback="parse_item"),  
 ]

 def parse_item(self,response):
  sel=Selector(response)
  item=DoubanmoiveItem()
  item['name']=sel.xpath('//*[@id="content"]/h1/span[1]/text()').extract()
  item['year']=sel.xpath('//*[@id="content"]/h1/span[2]/text()').re(r'\((\d+)\)')
  item['score']=sel.xpath('//*[@id="interest_sectl"]/div/p[1]/strong/text()').extract()
  item['director']=sel.xpath('//*[@id="info"]/span[1]/a/text()').extract()
  item['classification']= sel.xpath('//span[@property="v:genre"]/text()').extract()
  item['actor']= sel.xpath('//*[@id="info"]/span[3]/a[1]/text()').extract()
  return item

代碼說明: MoiveSpider 繼承Scrapy中的 CrawlSpider , name , allow_domains , start_url 看名字就知道什么含義,其中rules稍微復(fù)雜一些,定義了URL的抓取規(guī)則,符合 allow 正則表達(dá)式的鏈接都會加入到Scheduler(調(diào)度程序)。通過分析豆瓣電影Top250的分頁URL http://movie.douban.com/top250?start=25&filter=&type= 可以得到以下規(guī)則

Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/top250\?start=\d+.*'))),
而我們真正要抓取的頁面是每一個電影的詳細(xì)介紹,如肖申克的救贖的鏈接為 http://movie.douban.com/subject/1292052/ ,那只有 subject 后面的數(shù)字是變化的,根據(jù)正則表達(dá)式得到如下代碼。我們需要抓取這種類型鏈接中的內(nèi)容,于是加入callback屬性,將Response交給parse_item函數(shù)來處理。

Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/subject/\d+')),callback="parse_item"),     
在 parse_item 函數(shù)中的處理邏輯非常簡單,獲取符合條件鏈接的代碼,然后根據(jù)一定的規(guī)則抓取內(nèi)容賦給item并返回 Item Pipeline 。獲取大部分標(biāo)簽的內(nèi)容不需要編寫復(fù)雜的正則表達(dá)式,我們可以使用 XPath 。 XPath 是一門在 XML 文檔中查找信息的語言,但它也可以用在HTML中。下表列出了常用表達(dá)式。

表達(dá)式 描述
nodename 選取此節(jié)點的所有子節(jié)點。
/ 從根節(jié)點選取。
// 從匹配選擇的當(dāng)前節(jié)點選擇文檔中的節(jié)點,而不考慮它們的位置。
. 選取當(dāng)前節(jié)點。
.. 選取當(dāng)前節(jié)點的父節(jié)點。
@ 選取屬性。

如 //*[@id="content"]/h1/span[1]/text() 獲取的結(jié)果是在id為content的任意元素下h1元素下的span列表中第一個元素的文本內(nèi)容。我們可以通過Chrome開發(fā)者工具(F12)來獲取某內(nèi)容的XPath表達(dá)式,具體操作為在需要抓取的內(nèi)容上點擊審查元素,下方就會出現(xiàn)開發(fā)者工具,并定位到該元素,在內(nèi)容上點擊右鍵,選擇復(fù)制XPath。

2016120115233281.jpg (550×307)

存儲數(shù)據(jù)

爬蟲獲取到數(shù)據(jù)以后我們需要將其存儲到數(shù)據(jù)庫中,之前我們提到該操作需要靠項目管道(pipeline)來處理,其通常執(zhí)行的操作為:

  • 清洗HTML數(shù)據(jù)
  • 驗證解析到的數(shù)據(jù)(檢查項目是否包含必要的字段)
  • 檢查是否是重復(fù)數(shù)據(jù)(如果重復(fù)就刪除)
  • 將解析到的數(shù)據(jù)存儲到數(shù)據(jù)庫中

由于我們獲取的數(shù)據(jù)格式多種多樣,有一些存儲在關(guān)系型數(shù)據(jù)庫中并不方便,所以我在寫完MySQL版本的Pipeline之后又寫了一個MongoDB的。

MySQL版本: 

# -*- coding: utf-8 -*-
from scrapy import log
from twisted.enterprise import adbapi
from scrapy.http import Request

import MySQLdb
import MySQLdb.cursors


class DoubanmoivePipeline(object):
 def __init__(self):
  self.dbpool = adbapi.ConnectionPool('MySQLdb',
    db = 'python',
    user = 'root',
    passwd = 'root',
    cursorclass = MySQLdb.cursors.DictCursor,
    charset = 'utf8',
    use_unicode = False
  )
 def process_item(self, item, spider):
  query = self.dbpool.runInteraction(self._conditional_insert, item)
  query.addErrback(self.handle_error)
  return item

 def _conditional_insert(self,tx,item):
  tx.execute("select * from doubanmoive where m_name= %s",(item['name'][0],))
  result=tx.fetchone()
  log.msg(result,level=log.DEBUG)
  print result
  if result:
   log.msg("Item already stored in db:%s" % item,level=log.DEBUG)
  else:
   classification=actor=''
   lenClassification=len(item['classification'])
   lenActor=len(item['actor'])
   for n in xrange(lenClassification):
    classification+=item['classification'][n]
    if n<lenClassification-1:
     classification+='/'
   for n in xrange(lenActor):
    actor+=item['actor'][n]
    if n<lenActor-1:
     actor+='/'

   tx.execute(\
    "insert into doubanmoive (m_name,m_year,m_score,m_director,m_classification,m_actor) values (%s,%s,%s,%s,%s,%s)",\
    (item['name'][0],item['year'][0],item['score'][0],item['director'][0],classification,actor))
   log.msg("Item stored in db: %s" % item, level=log.DEBUG)

 def handle_error(self, e):
  log.err(e)

MongoDB版本:

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

from scrapy.exceptions import DropItem
from scrapy.conf import settings
from scrapy import log

class MongoDBPipeline(object):
 #Connect to the MongoDB database
 def __init__(self):
  connection = pymongo.Connection(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])
  db = connection[settings['MONGODB_DB']]
  self.collection = db[settings['MONGODB_COLLECTION']]

 def process_item(self, item, spider):
  #Remove invalid data
  valid = True
  for data in item:
   if not data:
   valid = False
   raise DropItem("Missing %s of blogpost from %s" %(data, item['url']))
  if valid:
  #Insert data into database
   new_moive=[{
    "name":item['name'][0],
    "year":item['year'][0],
    "score":item['score'][0],
    "director":item['director'],
    "classification":item['classification'],
    "actor":item['actor']
   }]
   self.collection.insert(new_moive)
   log.msg("Item wrote to MongoDB database %s/%s" %
   (settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
   level=log.DEBUG, spider=spider) 
  return item

可以看到其基本的處理流程是一樣,但是MySQL不太方便的一點就是需要將數(shù)組類型的數(shù)據(jù)通過分隔符轉(zhuǎn)換。而MongoDB支持存入List、Dict等多種類型的數(shù)據(jù)。

配置文件

在運行爬蟲之前還需要將在 settings.py 中增加一些配置信息。

BOT_NAME = 'doubanmoive'
SPIDER_MODULES = ['doubanmoive.spiders']
NEWSPIDER_MODULE = 'doubanmoive.spiders'
ITEM_PIPELINES={
 'doubanmoive.mongo_pipelines.MongoDBPipeline':300,
 'doubanmoive.pipelines.DoubanmoivePipeline':400,
}
LOG_LEVEL='DEBUG'

DOWNLOAD_DELAY = 2
RANDOMIZE_DOWNLOAD_DELAY = True
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'
COOKIES_ENABLED = True

MONGODB_SERVER = 'localhost'
MONGODB_PORT = 27017
MONGODB_DB = 'python'
MONGODB_COLLECTION = 'test'

ITEM_PIPELINES 中定義了MySQL和MongoDB兩個Pipeline文件,后面的數(shù)字代表執(zhí)行的優(yōu)先級順序,范圍為0~1000。 而中間的 DOWNLOAD_DELAY 等信息是為了防止爬蟲被豆瓣Ban掉,增加了一些隨機(jī)延遲,瀏覽器代理等。最后的就是MongoDB的配置信息,MySQL也可以參考這種方式來寫。

至此為止,抓取豆瓣電影的爬蟲就已經(jīng)完成了。在命令行中執(zhí)行 Scrapy crawl doubanmoive 讓蜘蛛開始爬行吧!

相關(guān)文章

  • PyTorch中的參數(shù)類torch.nn.Parameter()詳解

    PyTorch中的參數(shù)類torch.nn.Parameter()詳解

    這篇文章主要給大家介紹了關(guān)于PyTorch中torch.nn.Parameter()的相關(guān)資料,要內(nèi)容包括基礎(chǔ)應(yīng)用、實用技巧、原理機(jī)制等方面,文章通過實例介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Python制作運行進(jìn)度條的實現(xiàn)效果(代碼運行不無聊)

    Python制作運行進(jìn)度條的實現(xiàn)效果(代碼運行不無聊)

    這篇文章主要介紹了Python制作運行進(jìn)度條的實現(xiàn)效果(代碼運行不無聊),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • python正則表達(dá)式 匹配反斜杠的操作方法

    python正則表達(dá)式 匹配反斜杠的操作方法

    這篇文章主要介紹了python正則表達(dá)式 匹配反斜杠的操作方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • python代數(shù)式括號有效性檢驗示例代碼

    python代數(shù)式括號有效性檢驗示例代碼

    這篇文章主要給大家介紹了關(guān)于python代數(shù)式括號有效性檢驗的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Python正則表達(dá)式教程之二:捕獲篇

    Python正則表達(dá)式教程之二:捕獲篇

    什么是捕獲呢?使用小括號指定一個子表達(dá)式后,匹配這個子表達(dá)式的文本(即匹配的內(nèi)容)可以在表達(dá)式或者其他過程中接著用,下面這篇文章就主要介紹了Python正則表達(dá)式中關(guān)于捕獲的相關(guān)資料,需要的朋友可以參考下。
    2017-03-03
  • Python人工智能之sg2im文字轉(zhuǎn)圖像

    Python人工智能之sg2im文字轉(zhuǎn)圖像

    今天為大家介紹機(jī)器學(xué)習(xí)、深度學(xué)習(xí)中優(yōu)秀、有意思的 Python 源碼——sg2im的Code實踐教程,將文字轉(zhuǎn)為圖像。感興趣的朋友快來看看吧
    2021-11-11
  • pandas中的dataframe匯總和計算方法

    pandas中的dataframe匯總和計算方法

    這篇文章主要介紹了pandas中的dataframe匯總和計算方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 利用Python多線程實現(xiàn)圖片下載器

    利用Python多線程實現(xiàn)圖片下載器

    這篇文章主要介紹了利用Python多線程制作的圖片下載器的相關(guān)代碼,文中展示的示例代碼講解詳細(xì),對我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下
    2022-03-03
  • Python機(jī)器學(xué)習(xí)入門(一)序章

    Python機(jī)器學(xué)習(xí)入門(一)序章

    這篇文章主要介紹了Python機(jī)器學(xué)習(xí)入門知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • python批量爬取圖片的方法詳解

    python批量爬取圖片的方法詳解

    這篇文章給大家介紹了如何使用python批量爬取圖片,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12

最新評論