使用Scrapy抓取網頁內資料

可以經由撰寫幾行程式,透過Scrapy模組登入帳號與抓取資料,當然要事先了解Scrapy的運作流程。經由本程式以抓取zerojudge網站首頁(https://zerojudge.tw/)中「最新更新」的題目與題目網址。

(一)安裝Scrapy與建立專案

Step1)安裝Scrapy

執行「pip install scrapy」,因為使用Anaconda3,本身已經內建scrapy,所以就沒有安裝scrapy。

Step2)建立專案

在命令提示字元下,執行指令「scrapy startproject zj」,建立專案zj

Step3)建立spider

在命令提示字元下,執行指令「scrapy genspider zjindex zerojudge.tw」,建立名稱 zjindex的spider,指定擷取網站 zerojudge.tw。一個專案可以有許多spider,每個spider使用「scrapy crawl 指定的spider」,就可以使用指定的spider抓取資料。

此時在Windows命令提示字元下,使用指令「tree /F」可以列出目前資料夾下與檔案的狀態,除了zj\spider\zjindex.py為指令「scrapy genspider zjindex zerojudge.tw」所建立,其餘都是指令「scrapy startproject zj」所建立,以下說明各個檔案的用途。

D:\jupyter\zj> tree /F

列出磁碟區 Data 的資料夾 PATH

磁碟區序號為 8E74-5782

D:.

│ scrapy.cfg

└─zj

│ items.py ===========>儲存資料的結構

│ middlewares.py ======>分成spider middleware與downloader middleware

│ pipelines.py =========>用於整理、過濾與刪除資料item,並將資料插入資料庫

│ settings.py ==========>設定檔案

│ __init__.py

└─spiders ===========>所有spider放在此資料夾

zjindex.py =============>剛剛使用指令「scrapy genspider zjindex zerojudge.tw」建立的spider

__init__.py

(二)建立抓取資料的spider程式碼

Step4)編輯zj/spiders/zjindex.py,製作擷取網頁的程式

scrapy預設抓取start_urls所指定的網址,抓取後自動呼叫函式parse(第10到20行)進行資料處理,開啟檔案index.txt用於儲存最新題目的標題與網址。

使用瀏覽器瀏覽https://zerojudge.tw/Index,發現zerojudge首頁中最新更新的網頁如下

<div id="LatestProblem"><h4>最近更新</h4><table class="table table-condensed"><tbody><tr><td width="50%">c466. <a href="./ShowProblem?problemid=c466" title="[]"> 最新zerojudge更新題目</a>

所以使用「response.xpath('//div[@id="LatestProblem"]/table/tbody/tr/td/a/text()').extract()」抓取zerojudge首頁的「最新更新」所有題目標題儲存到title,使用「response.xpath('//div[@id="LatestProblem"]/table/tbody/tr/td/a/@href').extract()」抓取zerojudge首頁的「最新更新」的所有題目網址儲存到url,使用zip配對title與url,最後將title與url寫入檔案index.txt。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

# -*- coding: utf-8 -*-import scrapyclass ZjindexSpider(scrapy.Spider): name = 'zjindex' allowed_domains = ['zerojudge.tw'] index_url = 'https://zerojudge.tw/Index' start_urls = [index_url] def parse(self, response): filename = 'index.txt' with open(filename, 'wb') as f: #找出最近新增的題目與網址 title = response.xpath('//div[@id="LatestProblem"]/table/tbody/tr/td/a/text()').extract() url = response.xpath('//div[@id="LatestProblem"]/table/tbody/tr/td/a/@href').extract() result = zip(title, url) for a,b in result: f.write(a.encode(encoding="utf-8", errors="ignore")) f.write('\r\n'.encode(encoding="utf-8", errors="ignore")) f.write(b.encode(encoding="utf-8", errors="ignore")) f.write('\r\n'.encode(encoding="utf-8", errors="ignore"))

Step5)執行scrapy專案,在第一層的zj資料夾下,該zj資料夾內有檔案「scrapy.cfg」,在命令提示字元下執行指令「scrapy crawl zjindex 」,在第一層的zj資料夾下,產生檔案index.txt,該檔案內儲存「最新更新」的題目與題目網址。