IP[y]: Notebook

Installation:

  1. Install Python
  2. pip install ipython[notebook]
Successfully installed ipython gnureadline jinja2 pyzmq tornado markupsafe backports.ssl-match-hostname
Cleaning up...

Start Server:

ipython notebook
螢幕快照 2014-05-27 下午1.43.14.png
螢幕快照 2014-05-27 下午1.46.19.png

If there exists a *.ipynb file, it’ll be listed in the directory.

Then you can click it and get it launched.

螢幕快照 2014-05-27 下午1.46.35.png

More official reference: IP[y]: Notebook

[Python] Scrapy

Reference: Scrapy Documentation

Installation: pip install scrapy

Create Project: scrapy startproject [project name]

Project Directory Tree:
““
tutorial/
scrapy.cfg
tutorial/
init.py
items.py
pipelines.py
settings.py
spiders/
init.py

進入專案以後,我們首先要設定哪些項目是我們要抓的,因此要編輯 /tutorial/items.py:

from scrapy.item import Item, Field
class TutorialItem(Item):
title = Field()
link = Field()
desc = Field()

*這些 Field() 是在 scrapy.item 中定義的類別,在此我們宣告了三個 scrapy.item 的 Field 物件

接著就是要編寫我們的第一個 Crawler,在 /tutorial/spiders 中建立一個檔案 dmoz_spider.py(你的crawler檔):
from scrapy.spider import Spider

class DmozSpider(Spider):
  name = "dmoz"                        // 設定 crawler  的名稱
  allowed_domains = ["dmoz.org"]    // ???
  start_urls = [                    //  設定要爬的網頁 URL 列表
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
   "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
  ]

  /* 定義抓回來物件的處理函式 */
  def parse(self, response):
      filename = response.url.split("/")[-2]  // 從最後面開始擷取字元為 filename,並在遇到 '/' 時結束擷取
    with open(filename, "wb") as f:            // 建立或開啟名為 filename 的檔案,並指定為 f 
        f.write(response.body)              // 將物件 response 的 body 內容寫入檔案中
然後就可以執行這隻爬蟲程式,將上面兩個 URL 的網頁抓下來了,回到專案的根目錄,輸入:

scrapy crawl [spider_name]
“`

螢幕快照 2014-05-27 下午6.16.41.png

然後就得到下面的執行畫面,並且在根目錄下得到 Books 和 Resources 這兩個 URL 的網頁檔案

螢幕快照 2014-05-27 下午6.34.33.png

在 tutorial/spiders 中,我們可以編寫多個 spider,但是各個 spider 的名稱 (name 屬性) 必須唯一

Note:
本文參考的 Document 版本是 0.22.2,這個版本的專案預設 import 方式與 0.23.0 有點不一樣
在 0.22.2 的 from scrapy.xxx import …. 到了 0.23.0 中是 import scrapy
所以像是:

from scrapy.item import Item

class DmozItem(Item):

都要改成:

import scrapy

class DmozItem(scrapy.Item):

另外要注意的是,from 那邊是 item,import 是 Item,大小寫不一樣!

[Python] Python/C API On Linux Mint

今天第一次嘗試使用 Python/C API

但是花了點時間處理 GCC 編譯器引入 Python.h 的問題
———————————————————————————–

Python/C 是 Python 作為黏合語言的一個重點,要用 C 呼叫 Python 的模組,或是在 C 中使用 Python 語法,基本上需要透過這個 API ,其中有一個主要的 Header 叫做 Python.h,需要在其他標頭檔之前引入,接著就可以呼叫這個標頭檔中定義一些與 Python 有關的 C 函式了

我實驗的平台是 Linux Mint x86_64 3.8.0-19-generic 、Python 2.7.4、GCC 4.7.3

這台電腦中的  Python 沒有包含 Python.h 及其他相關的 Python Header,上網查可以很輕易找到要安裝 python-dev:sudo apt-get install python-dev,如此在 /usr/include/python2.7 裡面就有Python.h 了

然後我寫了以下的 C 範例 (python_in_c.c):

接著就很期待的要進行編譯:gcc -o a.out python_in_c.c
結果編譯錯誤!
訊息說找不到 Python.h,基本上網路上很多說安裝好 python-dev 以後就可以讓 C 編譯器在編譯時找到 Python.h 了

但我的結果是無法自動找到,進一步搜尋到相同狀況的文章說需要將路徑加入到 Compiler Search Path,所以我嘗試編譯時這樣:
gcc -I/usr/include/python2.7 -o a.out python_in_c.c
接著就有找到這個 header 了!

但是!還是有錯誤啊!訊息如下:
python_in_c.c:(.text …): undefined reference to ‘Py_Initialize’
python_in_c.c:(.text …): undefined reference to ‘PyRun_SimpleStringFlags’
python_in_c.c:(.text …): undefined reference to ‘Py_Finalize’

這樣不就還是沒有成功引入嗎?
因為我有去 trace Python.h ,有引入 pythonrun.h
PyRun_SimpleStringFlag 就在那裡面,怎麼會還是沒定義?

後來測試很久終於找到成功的敘述了:
gcc -I/usr/include/python2.7 -o a.out python_in_c.c -lpython2.7

這樣子除了找的到 header ,也可以通過編譯找到定義函式了

接著就可以執行產生的可執行擋了!

如果覺得每次都要打 -I/usr/include/python2.7 很瑣碎,我找到的作法是將這個路徑加到 C_INCLUDE_PATH 這個環境變數中,開啟 .bashrc 加入如下:
export C_INCLUDE_PATH="/usr/include/python2.7:$C_INCLUDE_PATH"