以前也有寫過爬蟲,抓過網(wǎng)易云歌單和豆瓣讀書的數(shù)據(jù),當(dāng)時有兩個問題解決的不夠好, 自動化和登錄。最近花時間用scrapy去寫,自認(rèn)為更好的解決了上述問題。這篇文章當(dāng)作一個記錄,也可當(dāng)作學(xué)習(xí)教程(需要BeautifulSoup, selenium基本知識)。
目標(biāo)
用scrapy去抓取自從有了知乎,再也不用找福利了……收藏夾下每一個答案下的全部圖片。
簡易步驟
- 賬號登錄知乎,抓取全部答案的鏈接(去除重復(fù)文章,大概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': '你覺得健身時哪個訓(xùn)練動作最酷炫?', 'dec': ['健身']}
{'url': '/question/28586345', 'title': '有馬甲線是種怎樣的體驗?', 'dec': ['馬甲線']}
{'url': '/question/68734869', 'title': '2017 年,你解鎖了哪些運動技能?可以用「視頻」展示么?', 'dec': ['解鎖']}
{'url': '/question/31983868', 'title': '有什么好看的泳裝推薦?', 'dec': ['泳裝']}
如上,對每一個問題提取url, 標(biāo)題和關(guān)鍵字,保存到j(luò)son文件方便后續(xù)工作。
- 對每一個答案,抓取該答案下所有圖片鏈接, 保存或者下載(此處用到selenium)。
-
結(jié)果:半天時間抓去圖片20000+張, 部分如下:
屏幕快照 2017-12-23 23.18.04.png
詳細(xì)步驟
一. 先從2開始,目標(biāo):如何拍好私房照?鏈接下的所有圖片。
- 新建工程 :
scrapy start zhihu
簡單介紹一下,工程目錄:
image.png
zhihu/spiders
:爬蟲的主要文件。
zhihu/items.py
:需要抓取的數(shù)據(jù)結(jié)構(gòu)
zhihu/middlewares.py
:中間鍵文件,selenium處理動態(tài)網(wǎng)頁。
zhihu/pipelines.py
:保存items中定義的數(shù)據(jù)結(jié)構(gòu)或者下載圖片(處理item)。
其余文件都是額外生成,不屬于爬蟲目錄。
cookies.pkl
:保存登錄的cookies, 下次登錄。
questions.json
: 保存所有問題的鏈接,方便后續(xù)使用。
上面兩個文件都是在第一步用到, 后續(xù)再講。
- 最簡單的爬蟲
相信看到這的童鞋都有用過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
執(zhí)行得到生成器, scrapy
經(jīng)過網(wǎng)絡(luò)請求返回后調(diào)用parse
函數(shù)。
接下來在項目目錄執(zhí)行scrapy crawl zhihu
啟動爬蟲,看輸出結(jié)果。
可以看到輸出的url和html代碼,最簡單的爬蟲執(zhí)行完畢。
關(guān)鍵:該開始運行一定要日志輸出。
遇到上述問題,需要打開
settings
文件做如下設(shè)置:
#重試設(shè)置
RETRY_ENABLE = False
# 日志輸出
LOG_ENABLED = True
LOG_LEVEL = "INFO"
取消失敗重試,設(shè)置日志級別和是否輸出(對爬取無影響)。
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
}
下載中間鍵中取消默認(rèn)的UserAgent設(shè)置,以。及對robos.txt的設(shè)置。
- 提取圖片鏈接。(BeautifulSoup)
關(guān)于BeautifulSoup
的使用可以看官方文檔,簡單明了。
獲取圖片的css selector,提取圖片鏈接。
打開該url, 右擊任何一張圖片,檢查即可看到該圖片的位置。
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
函數(shù)中,使用BeautifulSoup對網(wǎng)頁分析。
結(jié)果如下:
對比輸出,共計找到30個
figure
標(biāo)簽。分別對
figure
,figure
的子標(biāo)簽img
及其data-original
屬性進行輸出。粘貼屬性到瀏覽器打開即可看到圖片。
到此為止, 對如何拍好私房照?鏈接第一頁的圖片基本抓取完成。后面介紹怎么使用selenium對該鏈接下所有圖片進行抓取。
有疑問請加weixin:youquwen1226,一起探討。
github:https://github.com/yunshuipiao