本文分享的大體框架包含以下三部分
(1)首先介紹html網(wǎng)頁(yè),用來(lái)解析html網(wǎng)頁(yè)的工具xpath
(2)介紹python中能夠進(jìn)行網(wǎng)絡(luò)爬蟲的庫(kù)(requests,lxml,scrapy等)
(3)從四個(gè)案例出發(fā)有易到難依次介紹scrapy集成爬蟲框架
下面開始對(duì)三部分內(nèi)容逐一開始介紹。
一、html和xpath說(shuō)明
1. html
超文本標(biāo)記語(yǔ)言,是用來(lái)描述網(wǎng)頁(yè)的一種語(yǔ)言。主要用于控制數(shù)據(jù)的顯示和外觀。HTML文檔一定意義上可以被稱為網(wǎng)頁(yè)。但反過(guò)來(lái)說(shuō)網(wǎng)頁(yè)不僅僅是HTML,網(wǎng)頁(yè)本質(zhì)有三部分構(gòu)成:負(fù)責(zé)內(nèi)容結(jié)構(gòu)的HTML,負(fù)責(zé)表現(xiàn)的CSS,以及負(fù)責(zé)行為的javascript。本文主要分享的是最核心的內(nèi)容結(jié)構(gòu)部分。
(1)html結(jié)構(gòu)
完整的HTML文件至少包括<HTML>標(biāo)簽、<HEAD>標(biāo)簽、<TITLE>標(biāo)簽和<BODY>標(biāo)簽,并且這些標(biāo)簽都是成對(duì)出現(xiàn)的,開頭標(biāo)簽為<>,結(jié)束標(biāo)簽為</>,在這兩個(gè)標(biāo)簽之間添加內(nèi)容。通過(guò)這些標(biāo)簽中的相關(guān)屬性可以設(shè)置頁(yè)面的背景色、背景圖像等。
例如,我們打開豆瓣首頁(yè),摁下鍵盤上的F12鍵,打開瀏覽器自帶“開發(fā)者工具”,可以看到一個(gè)完整的html文檔結(jié)構(gòu),如下圖

從上圖可以看出,一個(gè)完整的html文檔主要包含三部分:DTD文檔頭,head頭部信息和body正文信息。其中DTD文檔頭用來(lái)告訴瀏覽器執(zhí)行標(biāo)準(zhǔn)是什么(比如html4或是html5),head頭部信息用來(lái)說(shuō)明瀏覽器的編碼方式和文檔頭名稱,body顧名思義就是瀏覽器的正文部分。
(2)html標(biāo)簽
作為開始和結(jié)束的標(biāo)記,由尖括號(hào)包圍的關(guān)鍵詞,比如 <html>,標(biāo)簽對(duì)中的第一個(gè)標(biāo)簽是開始標(biāo)簽,第二個(gè)標(biāo)簽是結(jié)束標(biāo)簽。html中常見標(biāo)簽如下:


其中, “< ul >< li ></li ></ul >”是一種嵌套順序,無(wú)序列表,成對(duì)出現(xiàn);li的父元素必須是ul或者ol,不同之處在于ol是一種有序列列表,而ul是無(wú)序列表;
(3)html屬性
屬性是用來(lái)修飾標(biāo)簽的,放在開始標(biāo)簽里里面,html中常見四大屬性:
| 屬性 | 說(shuō)明 |
|---|---|
| class | 規(guī)定元素的類名,大多數(shù)時(shí)候用于指定樣式表中的類 |
| id | 唯一標(biāo)識(shí)一個(gè)元素的屬性,在html里面必須是唯一的 |
| href | 指定超鏈接目標(biāo)的url |
| src | 指定圖像的url |
2. xpath
(1)xpath定義
是一種路徑查詢語(yǔ)言,簡(jiǎn)單的說(shuō)就是利用一個(gè)路徑表達(dá)式從html文檔中找到我們需要的數(shù)據(jù)位置,進(jìn)而將其寫入到本地或者數(shù)據(jù)庫(kù)中。(可以將xpath類比為sql結(jié)構(gòu)化查詢語(yǔ)言)
(2)xpath常見使用方法
| 符號(hào) | 功能 |
|---|---|
| // | 表示在整個(gè)文本中查找,是一種相對(duì)路徑 |
| / | 表示則表示從根節(jié)點(diǎn)開始查找,是一種絕對(duì)路徑 |
| text() | 找出文本值 |
| @ | 找出標(biāo)簽對(duì)應(yīng)的屬性值,比如@href就是找出對(duì)應(yīng)的href鏈接 |
| . | 表示當(dāng)前節(jié)點(diǎn) |
| .. | 表示當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn) |
當(dāng)然xpath除了上述常見用法外,還存兩種比較特殊的用法:以相同的字符開頭;標(biāo)簽套標(biāo)簽。
用法1:以相同的字符開頭:starts-with(@屬性部分,屬性字符相同部分
用法2:標(biāo)簽套標(biāo)簽:string(.)
#以相同的字符開頭
#比如我們想同時(shí)提取到下列html中三條文本內(nèi)容的話,就需要使用starts-with方法
html1 = """
<!DOCTYPE html>
<html>
<head lang='en'>
<meta charest='utf-8'>
<title></title>
</head>
<body>
<div id="test-1">需要的內(nèi)容1</div>
<div id="test-2">需要的內(nèi)容2</div>
<div id="testfault">需要的內(nèi)容3</div>
</body>
</html>
#爬取代碼
from lxml import etree
selector = etree.HTML(html1)
content = selector.xpath('//div[starts-with(@id,"test")]/text()')
for each in content:
print each
還有一種是標(biāo)簽套標(biāo)簽形式,參考如下例子
html2 = """
<!DOCTYPE html>
<html>
<head lang='en'>
<meta charest='utf-8'>
<title></title>
</head>
<body>
<div id="test3">
我左青龍,
<span id='tiger'>
右白虎
<ul>上朱雀,
<li>下玄武,</li>
</ul>
</span>
龍頭在胸口
</div>
</body>
</html>
"""
#如果我們想爬取的內(nèi)容是html文檔中的所有文本的話,需要使用string方法進(jìn)行提取
selector2 = etree.HTML(html2)
content2 = selector2.xpath('//div[@id="test3"]')[0] #列表,只有一個(gè)元素
info = content2.xpath('string(.)')
content3 = info.replace('\n','').replace(' ','')
print content3
(3)xpath的謂語(yǔ)結(jié)構(gòu)
該小節(jié)參考資料:阮一峰的網(wǎng)絡(luò)日志
所謂"謂語(yǔ)條件",就是對(duì)路徑表達(dá)式的附加條件。所有的條件,都寫在方括號(hào)"[]"中,表示對(duì)節(jié)點(diǎn)進(jìn)行進(jìn)一步的篩選。例如:
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
下面從幾個(gè)簡(jiǎn)單的例子讓大家體會(huì)一下
- /bookstore/book[1] :表示選擇bookstore的第一個(gè)book子元素。
- /bookstore/book[last()] :表示選擇bookstore的最后一個(gè)book子元素。
- /bookstore/book[last()-1] :表示選擇bookstore的倒數(shù)第二個(gè)book子元素。
- /bookstore/book[position()<3] :表示選擇bookstore的前兩個(gè)book子元素。
- //title[@lang] :表示選擇所有具有l(wèi)ang屬性的title節(jié)點(diǎn)。
- //title[@lang='eng'] :表示選擇所有l(wèi)ang屬性的值等于"eng"的title節(jié)點(diǎn)。
二、python中能夠進(jìn)行網(wǎng)絡(luò)爬蟲的庫(kù)
1. 安裝方式
python中安裝包或者模塊的方式一般有以下兩種:
(1)pip install xxx(xxx表示模塊名字)
pip install lxml/numpy/pandas/scrapy/requests
(2)進(jìn)入到python庫(kù)網(wǎng)站下載所需模塊,然后使用pip install xxx.whl安裝即可
pip install lxml?3.7.3?cp27?cp27m?win_amd64.whl
2. requests
import requests
#我的簡(jiǎn)書主頁(yè)
r = requests.get('http://www.itdecent.cn/u/95f3a80fac3e')
# r本身是一個(gè)reponse對(duì)象,需要通過(guò)content來(lái)返回其內(nèi)容
print r.content
#其實(shí)上面通過(guò)content之后得到就是一個(gè)完整的html文檔,之后可以直接使用lxml等工具直接對(duì)其進(jìn)行解析,下一小節(jié)會(huì)講到lxml
print r.status_code
print r.encoding #html的編碼方式,一般是UTF-8
print r.cookies
3. lxml
lxml中集成了剛才講述的xpath這種路徑查詢語(yǔ)言;例如我們首先創(chuàng)建一個(gè)html文檔如下
html= """
<!DOCTYPE html>
<html>
<head lang='en'>
<meta charest='utf-8'>
<title></title>
</head>
<body>
<div id="test-1">需要的內(nèi)容1</div>
<div id="test-2">需要的內(nèi)容2</div>
<div id="testfault">需要的內(nèi)容3</div>
</body>
</html>
"""
然后使用lxml對(duì)我們想要的內(nèi)容進(jìn)行爬取
from lxml import etree
selector = etree.HTML(html)
content = selector.xptah('path') #此處的path指的就是需要爬蟲的文件路徑
for item in content:
print item
前面講到的requests通常也是配合lxml使用,首先使用requests獲取到網(wǎng)頁(yè)內(nèi)容,即html文檔,然后使用lxml中的xpath爬取我們所需要的內(nèi)容。例子如下:
#爬取豆瓣電影top250,并將電影名稱和評(píng)分打印出來(lái)
import requests
from lxml import etree
s = requests.Session() #開啟一個(gè)requests會(huì)話
for id in range(0, 251, 25):
url = 'https://movie.douban.com/top250/?start-' + str(id)
r = s.get(url) #返回是一個(gè)reponse對(duì)象
r.encoding = 'utf-8'
root = etree.HTML(r.content)
items = root.xpath('//ol/li/div[@class="item"]')
# print(len(items))
for item in items:
title = item.xpath('./div[@class="info"]//a/span[@class="title"]/text()')
name = title[0].encode('gb2312', 'ignore').decode('gb2312')
# rank = item.xpath('./div[@class="pic"]/em/text()')[0]
rating = item.xpath('.//div[@class="bd"]//span[@class="rating_num"]/text()')[0]
print(name, rating)
4. 大殺器scrapy
scrapy是一個(gè)為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。 可以應(yīng)用在包括數(shù)據(jù)挖掘,信息處理或存儲(chǔ)歷史數(shù)據(jù)等一系列的程序中。我們需要知道的是,scrapy是一種集成框架,類似于request和xpath這些方法在scrapy都有集成。
(1)scrapy安裝
安裝scrapy前,需要先安裝lxml模塊,然后按照之前說(shuō)的方法進(jìn)行安裝就可以(我的電腦安裝的是anaconda集成環(huán)境)
(2)scrapy的結(jié)構(gòu)

其中,不同模塊負(fù)責(zé)不同的任務(wù)分工。首先Scheduler發(fā)出請(qǐng)求(Requests),Downloader負(fù)責(zé)從互聯(lián)網(wǎng)上下載內(nèi)容,將下載好的內(nèi)容(Responses)交給Spiders進(jìn)行解析,解析完成后將內(nèi)容Item返回,當(dāng)然其中可能會(huì)涉及到對(duì)于解析后數(shù)據(jù)的進(jìn)一步處理,這個(gè)任務(wù)是在Pipeline中完成的。
(3)scrapy通常有兩種使用方式:
- 直接在python腳本里定義一個(gè)爬取數(shù)據(jù)的類(參見爬蟲案例1,2,3)
- 創(chuàng)建完整的scrapy項(xiàng)目(參見爬蟲案例4);創(chuàng)建命令為
scrapy startproject xxx
創(chuàng)建完scrapy項(xiàng)目后,會(huì)在對(duì)應(yīng)的文件下生成如下結(jié)構(gòu):

其中,
spiders文件夾下面是真正爬蟲的代碼;
items之前提到過(guò),是定義需要爬取的內(nèi)容;
pipelines是對(duì)爬取到的數(shù)據(jù)進(jìn)行的進(jìn)一步處理;
settings中主要是一些環(huán)境變量和配置。
另外,scrapy有提供兩個(gè)xpath選擇器,HtmlXPathSelector和XmlXPathSelector,一個(gè)用于html,一個(gè)用于xml,xpath選擇器有三個(gè)方法:
- select(xpath): 返回一個(gè)相對(duì)于當(dāng)前選中節(jié)點(diǎn)的選擇器列表(一個(gè)xpath可能選到多個(gè)節(jié)點(diǎn))
-
extract(): 返回選擇器(列表)對(duì)應(yīng)的節(jié)點(diǎn)的字符串(列表,類型就是python中的list)
-_ re(regex)_: 返回正則表達(dá)式匹配的字符串(分組匹配)列表
需要注意的是,如果爬取的頁(yè)面相對(duì)簡(jiǎn)單,爬取內(nèi)容較少,且不用對(duì)爬取到的數(shù)據(jù)做過(guò)多的后期處理,使用第一種,反之,使用第二種,當(dāng)然建立完整的scrapy項(xiàng)目肯定可以處理簡(jiǎn)單任務(wù)。
三、爬蟲案例
1. 想要爬取得內(nèi)容都在同一頁(yè)面
本實(shí)例中,我們通過(guò)scrapy爬取七月在線課程信息。
#scrapy runspider spider.py –o xxx.json(運(yùn)行時(shí)可以在命令窗口進(jìn)行)
import scrapy
class JulyeduSpider(scrapy.Spider):
name = "julyedu"
start_urls = ['https://www.julyedu.com/category/index'] #開始爬取網(wǎng)址,是一個(gè)list列表
# 定義解析頁(yè)面函數(shù)
def parse(self, response):
for julyedu_class in response.xpath('//div[@class="course_info_box"]'):
print julyedu_class.xpath('a/h4/text()').extract_first()
print julyedu_class.xpath('a/p[@class="course-info-tip"][1]/text()').extract_first()
print julyedu_class.xpath('a/p[@class="course-info-tip"][2]/text()').extract_first()
print response.urljoin(julyedu_class.xpath('a/img[1]/@src').extract_first())
print "\n"
# 返回函數(shù)值
yield {
'title':julyedu_class.xpath('a/h4/text()').extract_first(),
'desc': julyedu_class.xpath('a/p[@class="course-info-tip"][1]/text()').extract_first(),
'time': julyedu_class.xpath('a/p[@class="course-info-tip"][2]/text()').extract_first(),
'img_url': response.urljoin(julyedu_class.xpath('a/img[1]/@src').extract_first())
}
2. 想要爬去的內(nèi)容在多頁(yè),不同頁(yè)之間可以進(jìn)行人為拼接構(gòu)成(例如博客園 )
本實(shí)例中,我們利用scrapy爬取博客園中的信息,爬取內(nèi)容包括每條博文的標(biāo)題、鏈接、作者、評(píng)論等信息
class CnBlogSpider(scrapy.Spider):
name = "cnblogs"
allowed_domains = ["cnblogs.com"]
start_urls = [ 'http://www.cnblogs.com/pick/#p%s' % p for p in xrange(1, 11) ]
#定義解析函數(shù)
def parse(self, response):
for article in response.xpath('//div[@class="post_item"]'):
print article.xpath('div[@class="post_item_body"]/h3/a/text()').extract_first().strip()
print response.urljoin(article.xpath('div[@class="post_item_body"]/h3/a/@href').extract_first()).strip()
print article.xpath('div[@class="post_item_body"]/p/text()').extract_first().strip()
print article.xpath('div[@class="post_item_body"]/div[@class="post_item_foot"]/a/text()').extract_first().strip()
print response.urljoin(article.xpath('div[@class="post_item_body"]/div/a/@href').extract_first()).strip()
print article.xpath('div[@class="post_item_body"]/div[@class="post_item_foot"]/span[@class="article_comment"]/a/text()').extract_first().strip()
print article.xpath('div[@class="post_item_body"]/div[@class="post_item_foot"]/span[@class="article_view"]/a/text()').extract_first().strip()
print ""
yield {
'title': article.xpath('div[@class="post_item_body"]/h3/a/text()').extract_first().strip(),
'link': response.urljoin(article.xpath('div[@class="post_item_body"]/h3/a/@href').extract_first()).strip(),
'summary': article.xpath('div[@class="post_item_body"]/p/text()').extract_first().strip(),
'author': article.xpath('div[@class="post_item_body"]/div[@class="post_item_foot"]/a/text()').extract_first().strip(),
'author_link': response.urljoin(article.xpath('div[@class="post_item_body"]/div/a/@href').extract_first()).strip(),
'comment': article.xpath('div[@class="post_item_body"]/div[@class="post_item_foot"]/span[@class="article_comment"]/a/text()').extract_first().strip(),
'view': article.xpath('div[@class="post_item_body"]/div[@class="post_item_foot"]/span[@class="article_view"]/a/text()').extract_first().strip(),
}
3. 想要爬取的內(nèi)容存在頁(yè)面跳轉(zhuǎn)(例如騰訊社會(huì)新聞)
class QQNewsSpider(scrapy.Spider):
name = 'qqnews'
start_urls = ['http://news.qq.com/society_index.shtml']
def parse(self, response):
for href in response.xpath('//*[@id="news"]/div/div/div/div/em/a/@href'):
full_url = response.urljoin(href.extract())
yield scrapy.Request(full_url, callback=self.parse_question) #調(diào)用scrapy中Request方法,對(duì)合并后的網(wǎng)址進(jìn)行分析,調(diào)用函數(shù)是parse_question
#真正意義上解析頁(yè)面的函數(shù)
def parse_question(self, response):
print response.xpath('//div[@class="qq_article"]/div/h1/text()').extract_first()
print response.xpath('//span[@class="a_time"]/text()').extract_first()
print response.xpath('//span[@class="a_catalog"]/a/text()').extract_first()
print "\n".join(response.xpath('//div[@id="Cnt-Main-Article-QQ"]/p[@class="text"]/text()').extract())
print ""
yield {
'title': response.xpath('//div[@class="qq_article"]/div/h1/text()').extract_first(),
'content': "\n".join(response.xpath('//div[@id="Cnt-Main-Article-QQ"]/p[@class="text"]/text()').extract()),
'time': response.xpath('//span[@class="a_time"]/text()').extract_first(),
'cate': response.xpath('//span[@class="a_catalog"]/a/text()').extract_first(),
}
4. 通過(guò)創(chuàng)建scrapy工程的方式爬取全國(guó)34個(gè)省、市所屬的2290個(gè)地區(qū)的歷史天氣預(yù)報(bào)數(shù)據(jù),網(wǎng)址請(qǐng)戳這里,并將其保存為json格式
之前跟大家分享的案例大多是參照網(wǎng)絡(luò)視頻資源和相關(guān)博客資料,這兩天由于項(xiàng)目需要,爬取全國(guó)34個(gè)省、市所屬的2290個(gè)地區(qū)的歷史天氣預(yù)報(bào)數(shù)據(jù),真正動(dòng)手才發(fā)現(xiàn)“紙上得來(lái)終覺(jué)淺,絕知此事要躬行”的道理所在,整個(gè)過(guò)程碰到很多坑,也請(qǐng)教了一些牛人,終于將數(shù)據(jù)成功爬取到本地,在此記錄下整個(gè)爬取過(guò)程。
1. 多級(jí)頁(yè)面跳轉(zhuǎn)問(wèn)題
涉及到多級(jí)頁(yè)面跳轉(zhuǎn)才能爬取到數(shù)據(jù)的場(chǎng)景,有兩個(gè)方面是需要特別注意的,第一是確保整個(gè)頁(yè)面跳轉(zhuǎn)過(guò)程的邏輯正確,第二是跳轉(zhuǎn)到某個(gè)具體頁(yè)面使用xpath進(jìn)行路經(jīng)查詢時(shí),要保證xpath的寫的沒(méi)有問(wèn)題。
2. Scrapy終端(Scrapy shell)
Scrapy終端是一個(gè)交互終端,供您在未啟動(dòng)spider的情況下嘗試及調(diào)試您的爬取代碼。 其本意是用來(lái)測(cè)試提取數(shù)據(jù)的代碼,不過(guò)您可以將其作為正常的Python終端,在上面測(cè)試任何的Python代碼。
對(duì)于檢查xpath路徑查詢語(yǔ)言是否正確非常,舉個(gè)例子,我想要爬取某個(gè)城市2017年一月的天氣中的日期數(shù)據(jù),

根據(jù)html中提供的路徑,我寫了如下的xpath表達(dá)式
day = sel.xpath('//div[@class="tqtongji2"]/ul[position()>1]/li[1]/a/text()').extract()
具體對(duì)不對(duì),能不能爬取到相對(duì)應(yīng)的日期數(shù)據(jù),我們就可以利用scrapy shell進(jìn)行檢查。
(1)首先在命令窗口啟動(dòng)scrapy shell,啟動(dòng)語(yǔ)句也很簡(jiǎn)單,如下
scrapy shell url
其中url表示想測(cè)試的網(wǎng)頁(yè)鏈接。

(2)輸入需要檢查的xpath語(yǔ)句

可以看到輸出結(jié)果中已經(jīng)正確提取出我們需要的日期數(shù)據(jù),從而也說(shuō)明我們寫的xpath路徑?jīng)]有問(wèn)題。
3. 爬蟲正式開始
(1)建立scrapy工程
利用前面講到的方法創(chuàng)建相應(yīng)的scrapy工程,在item.py中創(chuàng)建需要爬去的數(shù)據(jù)如下:

(2)爬蟲spider腳本
我們打開需要爬取頁(yè)面的首頁(yè)如下,http://lishi.tianqi.com/,

從頁(yè)面中我們可以看到,全國(guó)各縣區(qū)的城市按照A,B,C...Z順序排列,每個(gè)字母下面包含很多城市,比如字母A下面包含阿城等地方。且每一類下面的第一個(gè)li標(biāo)簽是不需要的,因?yàn)榈谝粋€(gè)li標(biāo)簽表示的是字母A,B,C...Z等,如下圖

分析到這一步,我們可以寫出一級(jí)解析函數(shù)parse來(lái)獲取所有城市—鏈接和城市名的xpath路徑查詢語(yǔ)言,
鏈接如下:
sel = Selector(response)
country_urls = sel.xpath('//ul[@class="bcity"]/li[position()>1]/a/@href').extract()
城市名如下:
sel = Selector(response)
country_urls = sel.xpath('//ul[@class="bcity"]/li[position()>1]/a/text()').extract()
接下來(lái)就是每個(gè)城市(鏈接)進(jìn)行for循環(huán)遍歷,將每個(gè)城市的鏈接url和城市名城保存到item中,保存file_name目的在于為了待會(huì)兒寫入數(shù)據(jù)時(shí)方便。將所有獲取到的城市鏈接和城市名保存到items列表中,然后使用for循環(huán)對(duì)每個(gè)城市的進(jìn)行二級(jí)頁(yè)面解析,調(diào)用的是scrapy的Request方法,Request中的回調(diào)函數(shù)callback就是二級(jí)頁(yè)面解析函數(shù)second_parse。一級(jí)解析函數(shù)parse的完整代碼如下:

既然說(shuō)到二級(jí)頁(yè)面,我們還是首先觀察下二級(jí)頁(yè)面的特點(diǎn),以澳門歷史天氣詳情為例

可以看到,澳門所有歷史數(shù)據(jù)(按月)都在div class = "tqtongji" 標(biāo)簽下面,每年的數(shù)據(jù)又被一個(gè)ul標(biāo)簽包圍,每個(gè)ul標(biāo)簽下面擁有很多個(gè)li標(biāo)簽,分別表示一年的各個(gè)月份數(shù)據(jù),分析到此,我們同樣可以在二級(jí)解析頁(yè)面函數(shù)中寫出獲取每個(gè)城市每個(gè)月鏈接和月份名稱的xpath路徑
鏈接如下:
sel = Selector(response)
month_urls = sel.xpath('//div[@class="tqtongji1"]/ul/li/a/@href').extract()
城市名如下:
sel = Selector(response)
month_titles = sel.xpath('//div[@class="tqtongji1"]/ul/li/a/text()').extract()
同樣,獲取到每個(gè)城市每個(gè)月份的鏈接后,在二級(jí)解析函數(shù)里面對(duì)每個(gè)月份進(jìn)行遍歷,最后仍然使用scrapy.Request對(duì)每個(gè)獲取的月份鏈接進(jìn)行解析,回調(diào)函數(shù)是三級(jí)頁(yè)面解析函數(shù)detail_parse。
以下是二級(jí)頁(yè)面解析函數(shù)的腳本

最后跳轉(zhuǎn)到我們最終要爬取數(shù)據(jù)的頁(yè)面了,到了這一頁(yè)面之后(如下圖),便能夠很方便的爬取到我們需要的數(shù)據(jù)。

直接貼上最終三級(jí)頁(yè)面解析函數(shù)

到此,爬取數(shù)據(jù)的spider腳本已經(jīng)全部開發(fā)完成,不過(guò)為了將數(shù)據(jù)按照城市分別保存到本地,還需要在pipeline中進(jìn)行相應(yīng)設(shè)置如下:

最終爬取的效果圖如下圖:


喜歡的朋友請(qǐng)小小的點(diǎn)個(gè)贊,你的肯定會(huì)讓我更有動(dòng)力?。?!