透過 Scrapy 實作一個自由時報的新聞爬蟲
爬蟲 x 自由時報爬蟲實戰
爬蟲2 x 自由時報網站結構分析
爬蟲3 x XPath 工具介紹
爬蟲4 x Scrapy 框架介紹及實作
爬蟲5 x Scrapy 自由時報新聞實戰
爬蟲6 x Scrapy 自由時報新聞實戰2
有之前XPath的基礎下,我們能輕易地透過 下述XPath輕鬆抓出每一個新聞區塊(圖1)
//ul[@id="newslistul"]//li
Scrapy 實作程式碼
Scrapy class...
def parse(self, response):
blocks = response.xpath('//ul[@id="newslistul"]//li'):
print(len(blocks)) # 15 在撰寫這篇文章時,自由時報每頁會顯示15則新聞
而我們這邊每一個區塊(block)就是我們想要知道的新聞,我們再透過XPath取出這每一個block中的新聞連結,以方便我們進行下一步的新聞資料爬取,XPath效果如圖2.
//a[contains(@class, "tit")]/@href
[備註] 因為要取出a標籤的href(連結)屬性則透過 /@href 取得
Scrapy 實作程式碼
for block in response.xpath('//ul[@id="newslistul"]//li'):
href = block.xpath('.//a[contains(@class, "tit")]/@href').extract_first()
print(href) # news/politics/breakingnews/2842064 ...
由print(href)的output可知,我們成功透過這個XPath取得新聞正文的URL,下一步我們就要進行新聞正文的處理(parsing)。
由上述範例的連結我們可組成這樣的URL
https://news.ltn.com.tw/news/politics/breakingnews/2842064
這邊先留個伏筆,我們先來處理換頁的事情
爬取新聞不可能只爬取一頁,我們必須一頁一頁的將需要的資料擷取下來,這樣我們的爬蟲就必須要有換頁的功能,分析目標網站的分頁功能後,我們找到了下一頁的按鈕(如下圖3)。
//a[contains(@class, “p_next”)]/@href
結合之前parse的程式碼,我們透過response.follow(註1) 傳入href進行換頁
def parse(self, response):
for block in response.xpath('//ul[@id="newslistul"]//li'):
href = block.xpath('.//a[contains(@class, "tit")]/@href').extract_first()
print(href)
a_next = response.xpath('//a[contains(@class, "p_next")]/@href').extract_first()
if a_next:
yield response.follow(a_next, callback=self.parse)
完整程式碼如下
執行程式
# CLI
scrapy runspider ltn-scrapy-pagination.py2019-07-08 22:03:55 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://news.ltn.com.tw/search/?keyword=%E5%8F%8D%E7%B4%85%E5%AA%92> (referer: None)
news/world/breakingnews/2845612
news/entertainment/breakingnews/2845122
news/politics/paper/1301417
news/politics/breakingnews/2844675
news/entertainment/breakingnews/2844240
news/opinion/breakingnews/2843861
news/entertainment/breakingnews/2843289
news/entertainment/breakingnews/2843184
news/opinion/paper/1300953
news/politics/breakingnews/2842064
news/opinion/paper/1300464
news/life/breakingnews/2840838
news/politics/breakingnews/2840560
news/entertainment/breakingnews/2839953
news/politics/breakingnews/2839685
Reference
- Scrapy docs, Scrapy response follow