快上車,scrapy爬蟲飆車找福利(一)

swensun發表於2017-12-28

以前也有寫過爬蟲,抓過網易雲歌單和豆瓣讀書的資料,當時有兩個問題解決的不夠好, 自動化和登入。最近花時間用scrapy去寫,自認為更好的解決了上述問題。這篇文章當作一個記錄,也可當作學習教程(需要BeautifulSoup, selenium基本知識)。

目標

用scrapy去抓取自從有了知乎,再也不用找福利了……收藏夾下每一個答案下的全部圖片。

簡易步驟

  1. 賬號登入知乎,抓取全部答案的連結(去除重複文章,大概39個答案)。
{'url': '/question/36007260', 'title': '女生堅持健身是種什麼樣的體驗?', 'dec': ['健身']}
{'url': '/question/22132862', 'title': '女生如何選購適合自己的泳裝?', 'dec': ['泳裝']}
{'url': '/question/22918070', 'title': '女生如何健身鍛造好身材?', 'dec': ['健身']}
{'url': '/question/24214727', 'title': '大胸妹子如何挑選合身又好看的比基尼?', 'dec': [ '比基尼']}
{'url': '/question/263451180', 'title': '你覺得健身時哪個訓練動作最酷炫?', 'dec': ['健身']}
{'url': '/question/28586345', 'title': '有馬甲線是種怎樣的體驗?', 'dec': ['馬甲線']}
{'url': '/question/68734869', 'title': '2017 年,你解鎖了哪些運動技能?可以用「視訊」展示麼?', 'dec': ['解鎖']}
{'url': '/question/31983868', 'title': '有什麼好看的泳裝推薦?', 'dec': ['泳裝']}
複製程式碼

如上,對每一個問題提取url, 標題和關鍵字,儲存到json檔案方便後續工作。

  1. 對每一個答案,抓取該答案下所有圖片連結, 儲存或者下載(此處用到selenium)。
  2. 結果:半天時間抓去圖片20000+張, 部分如下:
    螢幕快照 2017-12-23 23.18.04.png

詳細步驟

一. 先從2開始,目標:如何拍好私房照?連結下的所有圖片。

  1. 新建工程 :scrapy start zhihu 簡單介紹一下,工程目錄:
    image.png
    zhihu/spiders:爬蟲的主要檔案。 zhihu/items.py:需要抓取的資料結構 zhihu/middlewares.py:中間鍵檔案,selenium處理動態網頁。 zhihu/pipelines.py:儲存items中定義的資料結構或者下載圖片(處理item)。

其餘檔案都是額外生成,不屬於爬蟲目錄。 cookies.pkl:儲存登入的cookies, 下次登入。 questions.json: 儲存所有問題的連結,方便後續使用。 上面兩個檔案都是在第一步用到, 後續再講。

  1. 最簡單的爬蟲 相信看到這的童鞋都有用過requests庫, BeautifulSoup去寫過簡單的爬蟲。 這裡不做討論。 在zhihu/spiders下新建zhihu.py檔案,從這裡開始。
import scrapy
class Zhihu(scrapy.Spider):
    name = "zhihu"
    urls = ["https://www.zhihu.com/question/22856657"]
    yield request

    def start_requests(self):
        for url in self.urls:
            request = scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        print(response.url)
        print(response.body)
複製程式碼

name定義了爬蟲的名字,urls定義需要爬取的連結,從start_requests開始,yield對每一個url執行得到生成器, scrapy經過網路請求返回後呼叫parse函式。 接下來在專案目錄執行scrapy crawl zhihu 啟動爬蟲,看輸出結果。

image.png
可以看到輸出的url和html程式碼,最簡單的爬蟲執行完畢。 關鍵:該開始執行一定要日誌輸出。
image.png
遇到上述問題,需要開啟settings檔案做如下設定:

#重試設定
RETRY_ENABLE = False

# 日誌輸出
LOG_ENABLED = True
LOG_LEVEL = "INFO"
複製程式碼

取消失敗重試,設定日誌級別和是否輸出(對爬取無影響)。

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
}
複製程式碼

下載中間鍵中取消預設的UserAgent設定,以。及對robos.txt的設定。

  1. 提取圖片連結。(BeautifulSoup) 關於BeautifulSoup的使用可以看官方文件,簡單明瞭。 獲取圖片的css selector,提取圖片連結。 開啟該url, 右擊任何一張圖片,檢查即可看到該圖片的位置。
    image.png

image.png
如上所示,即可找到該img的位置。 接下來看程式碼:

import scrapy
from bs4 import BeautifulSoup

class Zhihu(scrapy.Spider):
    name = "zhihu"
    urls = ["https://www.zhihu.com/question/22856657"]


    def start_requests(self):
        for url in self.urls:
            request = scrapy.Request(url=url, callback=self.parse)
            yield request

    def parse(self, response):
        print(response.url)
        resSoup = BeautifulSoup(response.body, 'lxml')
        items = resSoup.select("figure")
        print(len(items))
        for item in items:
            print(item)
            print(item.img)
            print(item.img['data-original'])
複製程式碼

parse函式中,使用BeautifulSoup對網頁分析。 結果如下:

image.png
對比輸出,共計找到30個figure標籤。 分別對figure,figure的子標籤img 及其data-original屬性進行輸出。 貼上屬性到瀏覽器開啟即可看到圖片。 到此為止, 對如何拍好私房照?連結第一頁的圖片基本抓取完成。後面介紹怎麼使用selenium對該連結下所有圖片進行抓取。

有疑問請加weixin:youquwen1226,一起探討。 github:https://github.com/yunshuipiao

相關文章