1 問題描述
通過Scrapy,實現CSDN熱門博客抓取,並以博客大標題對本地HTML的命名
2 解題提示
- 創建Scrapy項目: Scrapy startproject 【項目名稱】
- 創建Spider文件: Scrapy genspider 【爬蟲文件名】 “【allowed_domain】”
- 開啓項目文件: Scrapy crawl 【爬蟲文件名】
- yield Request 向調度器發送一個請求,yield dict 向管道文件發送一個數據
- Request中的callback爲得到響應後的回調函數
3 評分標準
- 完成Scrapy項目的搭建 10分
- 實現熱門博客抓取與本地保存 10分
- 代碼註釋,規範10分
4 要點解析
- scrapy 原理介紹
- 各組件功能介紹
5 實現步驟
- 創建scrapy框架
- 創建spider文件
- 編輯爬蟲文件
# -*- coding: utf-8 -*-
import scrapy
import urllib.request as ur
import urllib.parse as up
class BlogspiderSpider(scrapy.Spider):
# name同spider的名字一致
name = 'blog_spider'
# 可以過濾不是本web的request
allowed_domains = ['blog.csdn.net']
keyword = 'python進階'
# 定義start_request可以封裝headers,以及代理IP
# start_urls = ['http://blog.csdn.net/']
def start_requests(self):
# 熱門blog的網頁解析,其中中文需要轉譯:還是採用用戶端輸入的形式,不定頁面以及關鍵詞了
# pn_start = int(input("起始頁:"))
# pn_end = int(input("結束頁:")) # 實際爬蟲獲取最大頁面
# keyword = input("關鍵詞:")
# 循環頁面
pn_start = 1
pn_end = 10
for pn in range(pn_start, pn_end + 1):
url_data = {
'p': pn,
'q': self.keyword
}
# 編碼關鍵詞
url_data = up.urlencode(url_data)
# 構建url
url = 'https://so.csdn.net/so/search/s.do?%s&t=blog&viparticle=&domain=&o=&s=&u=&l=&f=&rbg=0' % url_data
yield scrapy.Request(
url=url,
callback=self.parse,
)
# 將start_request產生的response傳遞給parse,並進行處理
def parse(self, response):
# 這個response是bytes類型,可以直接xpath找到熱門文章
# href_s是一個列表,並且xpath是scrapy的形式,使用extract()
href_s = response.xpath('//div[@class="limit_width"]/a[1]/@href').extract()
# 處理每一個href對應的熱門博客,並且返回start_request
for href in href_s:
yield scrapy.Request(
url=href,
callback=self.parse2,
)
def parse2(self, response):
# 不取索引0,使用extract_first
title = response.xpath('//div[@class="article-title-box"]/h1/text()').extract_first()
# html 文件,body等同於ur.urlopen().read()
data = response.body
# 封裝item,並且傳遞給pipeline
item = dict(
title=title,
data=data,
)
# scheduler 引擎會自動判斷
yield item
- 存儲數據
class Homework1Pipeline(object):
def process_item(self, item, spider):
# 獲取item的title,data值
# 將html存儲當csdn_blog文件夾裏
with open('csdn_blog/%s.html' % item['title'], 'wb') as f:
f.write(item['data'])
return item
- 開啓項目文件