Python Scrapy 爬蟲框架 | 3、利用 Scrapy 爬取部落格文章詳細資訊

  • 2019 年 12 月 30 日
  • 筆記

0x00 寫在前面

在之前的文章中,會發現如果直接使用爬取命令,終端會回顯很多調試資訊,這樣輸出的內容就會顯得很亂,所以就可以使用下面的命令:

scrapy crawl blogurl  -s LOG_FILE=all.log

也就是在原來的基礎上加上一個 -s 參數,這樣調試資訊就會保存到參數指定的文件中,不過也可以在 class 下添加下面的程式碼,這樣只會顯示調試出現錯誤的資訊,所以這種方式就不用加 -s 了,至於選擇哪一個,就需要視情況而定。

custom_settings = {'LOG_LEVEL':'ERROR'}

0x01 編寫子頁面爬取程式碼

先來看一行關鍵程式碼

yield scrapy.Request(url,callback=self.sub_article)

上面這行程式碼中,使用 yield 返回利用 scrapy 請求 url 所獲得的數據,並將數據通過 callback 傳遞到 sub_article 函數中。

其實對於 yield 和 return 都可以返回數據,但是利用 yield 返回數據後,還可以繼續運行下面的程式碼,而使用 return 後,接下來的程式碼就不會再運行了,在 scrapy 中,如果使用 return 返回數據再用 list 存儲數據,會造成不少的記憶體消耗,而使用 yield 則可以減少這些不必要的記憶體浪費。

所以接下來在 sub_article 函數中寫上我們爬取子頁面的程式碼即可,這裡就爬取每個文章的標題和目錄作為示例了。

def sub_article(self,response):     soup = BeautifulSoup(response.text,'html.parser')     print('n',soup.select('.title')[0].text)     for i in soup.select('.toc-text'):        print('t',i.text)

運行結果如下:

~# scrapy crawl blogurl  -s LOG_FILE=all.log  【漏洞筆記】Robots.txt站點文件           0x00 概述           0x01 漏洞描述           0x02 漏洞危害           0x03 修復建議  【經驗總結】常見的HTTP方法           0x00 概述           0x01 GET           0x02 HEAD           0x03 POST           0x04 PUT           0x05 DELETE           0x06 CONNECT           0x07 OPTIONS           0x08 TRACE           0x09 PATCH  【漏洞筆記】Host頭攻擊           0x00 概述           0x01 漏洞描述           0x02 漏洞危害           0x03 修復建議  【直播筆記】白帽子的成長之路  【Python 學習筆記】 非同步IO (asyncio) 協程           0x00 前言           0x01 基本用法  ……省略……

0x02 完整程式碼

import scrapy  from bs4 import BeautifulSoup    class BlogSpider(scrapy.Spider):     name = 'blogurl'     start_urls = ['https://www.teamssix.com']       def parse(self,response):        soup = BeautifulSoup(response.text,'html.parser')        for i in soup.select('.post-title'):           url = 'https://www.teamssix.com{}'.format(i['href'])           yield scrapy.Request(url,callback=self.sub_article)       def sub_article(self,response):        soup = BeautifulSoup(response.text,'html.parser')        title = self.article_title(soup)        list = self.article_list(soup)        print(title)        for i in list:           print('t',i)       def article_title(self,soup):        return soup.select('.title')[0].text       def article_list(self,soup):        list = []        for i in soup.select('.toc-text'):           list.append(i.text)        return list

參考鏈接: https://youtu.be/aDwAmj3VWH4 https://blog.csdn.net/DEREK_D/article/details/84239813 http://doc.scrapy.org/en/latest/topics/architecture.html