scrapy 爬取 去哪網(wǎng) 游記內(nèi)容 圖片

書接上文它浅,前面用pyspider實現(xiàn)了去哪網(wǎng)的游記爬取數(shù)據(jù)存儲
然后學(xué)習(xí)了scrapy之后羊娃,用scrapy再次實現(xiàn)了一次翼馆,通過實際操做东且,加深對scrapy的理解

環(huán)境介紹:
MacOS Mojave 10.14.5+VSCode1.37.1+Python3.7

1 創(chuàng)建項目

scrapy start project quna

然后項目就創(chuàng)建好了

(base) bogon:~ blaze$ scrapy startproject qunaScrapy
New Scrapy project 'qunaScrapy', using template directory '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scrapy/templates/project', created in:
    /Users/blaze/qunaScrapy

You can start your first spider with:
    cd qunaScrapy
    scrapy genspider example example.com
(base) bogon:~ blaze$ cd qunaScrapy/
(base) bogon:qunaScrapy blaze $ ls
qunaScrapy      scrapy.cfg
(base) bogon:qunaScrapy blaze$ 

2 創(chuàng)建Spider

scrapy genspider quna travel.qunar.com

查看工程目錄下的文件


image.png

而我們處理的就是spiders目錄下的quna.py

image.png

上面是剛創(chuàng)建的
下面放出爬取去哪網(wǎng)的完整代碼,相關(guān)的點启具,我都在代碼里做了注釋
quna.py

# -*- coding: utf-8 -*-
import os
import scrapy
from scrapy import Selector
from qunaScrapy.items import ImageItem #后面會有講解

#設(shè)置爬取結(jié)果存放的路徑
DIR_PATH = '/Users/lzx-mac-baibing/Desktop/去哪網(wǎng)游記Scrapy'
#設(shè)置分頁請求的數(shù)量上限
MAX_PAGE = 50


class QunaSpider(scrapy.Spider):
    #項目的唯一名,用來區(qū)分不同的Spider   
    name = 'quna' 
    #允許爬取的域名珊泳,凡事不在這里的域名下的請求鲁冯,都會被過濾  
    allowed_domains = ['travel.qunar.com','tr-osdcp.qunarzz.com']
    #spider啟動時拷沸,初始化請求的地址
    start_urls = ['http://travel.qunar.com/travelbook/list.htm/']
    #分頁請求時使用    
    page=1

    def __init__(self):
        #初始化文件操作類
        self.deal = Deal()
    
    #初始化請求默認回掉的方法,作為我們所有解析的入口
    #作為scrapy的學(xué)習(xí)項目薯演,這里我只是實現(xiàn)了爬取第一頁數(shù)據(jù)并獲取對應(yīng)詳情的邏輯
    #如果有需要撞芍,也可以在parse中實現(xiàn)再套一層邏輯,處理page切換
    def parse(self, response):
        #這里獲取的li標簽下跨扮,class=tit a標簽的href數(shù)據(jù)序无,也就是所有標題關(guān)聯(lián)的相對url地址
        #對應(yīng)的網(wǎng)頁數(shù)據(jù)如下圖圖片A所示結(jié)構(gòu)
        for each in response.css('li > .tit > a').xpath('@href').extract():
            #用獲取的相對路徑生成完整的路徑
            url = response.urljoin(each)
            #回掉詳情
            yield scrapy.Request(url=url,callback=self.detail_page,dont_filter=True)

    ##對應(yīng)帶分頁數(shù)據(jù)請求的parse方法
    # def parse(self, response):
    #     print('====================== ',self.page)
    #     for each in response.css('li > .tit > a').xpath('@href').extract():
    #         url = response.urljoin(each)
    #         yield scrapy.Request(url=url,callback=self.detail_page,dont_filter=True)
    #     if self.page < MAX_PAGE:
    #         self.page += 1
    #         next = response.css('.next').xpath('@href').extract_first()
    #         if next:
    #             nextUrl = next
    #             if next.startswith('http')==False:
    #                 if next.startswith('//'):
    #                     nextUrl = 'http:'+ next
    #             yield scrapy.Request(url=nextUrl,callback=self.parse,dont_filter=True)


    #詳情解析
    def detail_page(self,response):
        #獲取圖片地地址 class=js_lazyimg  標簽下的data-original屬性
        images = response.css('.js_lazyimg').xpath('@data-original').extract()
        #獲取title id=booktitle 的文本信息
        title = response.css('#booktitle::text').extract_first()
        #給每個游記用title創(chuàng)建個文件夾
        dir_path = self.deal.mkDir(title)
        #圖片多了有些亂,加個目錄存放圖片
        self.deal.mkDir(title+'/圖片')
        #獲取標簽以及子標簽的文本衡创,遍歷所有的元素帝嗡,獲得標簽文本
        contents = response.xpath('//div[@class="b_panel_schedule"]//text()').extract()
        #將獲取的搜有內(nèi)容文本,給他拼起來
        content = ''
        for text in contents:
            content = content + '\n' + text
        if dir_path:
            #將文本信息以txt存儲到指定目錄下璃氢,也就是我們前面創(chuàng)建的文件夾下
            self.deal.saveContent(content,dir_path,title)
            #圖片的處理哟玷,后續(xù)詳解
            for img in images:
                if img:
                    file_name = self.deal.getFileName(img)
                    file_path = dir_path+'/圖片/'+file_name
                    item = ImageItem()
                    item['src'] = [img]
                    item['dir_path']=file_path
                    yield item

#下面這些就不講了
class Deal:
    def __init__(self):
        self.path = DIR_PATH
        if not self.path.endswith('/'):
            self.path = self.path + '/'
        if not os.path.exists(self.path):
            os.makedirs(self.path)
    def mkDir(self, path):
        path = path.strip()
        dir_path = self.path + path
        exists = os.path.exists(dir_path)
        if not exists:
            os.makedirs(dir_path)
            return dir_path
        else:
            return dir_path
    def saveContent(self, content, dir_path, name):
        file_name = dir_path + "/" + name + ".txt"
        f = open(file_name, "w+")
        f.write(content)
    def getFileName(self, url):
        (url, tempfilename) = os.path.split(url)
        return tempfilename

圖片A

3 創(chuàng)建item

item 是保存爬取數(shù)據(jù)的容器,和字典類似拔莱,比字典多了額外保護碗降,可以避免拼寫錯誤或者定義字段錯誤,反正就是直接報錯……別問我咋知道的??

我們后續(xù)需要使用的就是下載地址和保存路徑
完整代碼如下
item.py

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy

class ImageItem(scrapy.Item):
    src=scrapy.Field()
    dir_path=scrapy.Field()

然后spider中用from qunaScrapy.items import ImageItem導(dǎo)入即可

上述的完工了塘秦,就能啟動爬蟲了讼渊,只是圖片沒法下載和存儲

scrapy crawl quna

接下來,我們需要處理圖片

4 設(shè)置Item Pipeline

項目管道尊剔,當item生成后爪幻,會自動被送到這來處理。

代碼實現(xiàn)如下 pipelines.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import scrapy
from qunaScrapy.items import ImageItem
import shutil,os,pymysql
from scrapy.pipelines.images import ImagesPipeline

#這個生成項目的時候就有了须误,必須實現(xiàn)process_item
class QunascrapyPipeline(object):
    def process_item(self, item, spider):
        return item
    
#自定義實現(xiàn)文件下載處理

#def item_completed(self,results,sipders...):
class QunaImgDownloadPipeline(ImagesPipeline):
    #獲取圖片地址,發(fā)起請求
    def get_media_requests(self, item, info): 
        for image_url in item['src']:
            yield scrapy.Request(image_url)
    #下載結(jié)束后回調(diào)的方法
    def item_completed(self, results, item, info):
        #獲取圖片的保存的相對路徑挨稿,full/****.jpg
        image_paths = [x['path'] for ok, x in results if ok]
        #生成完全地址
        readl_path = '/Users/lzx-mac-baibing/Desktop/去哪網(wǎng)游記Scrapy/圖集'+'/'+image_paths[0]
        #將下載好的文件,移到對應(yīng)的游記目錄下
        shutil.move(readl_path,item['dir_path'])
        return item

4 配置setting 激活管道

修改部分的代碼如下

#鍵-需要打開的ItemPipeline類
#值-優(yōu)先級京痢,數(shù)字0-1000奶甘,數(shù)字越小,優(yōu)先級越高
ITEM_PIPELINES = {
    'qunaScrapy.pipelines.QunascrapyPipeline': 1000,
    'qunaScrapy.pipelines.QunaImgDownloadPipeline':1
}
#設(shè)置的full文件存放的路徑
IMAGES_STORE = '/Users/lzx-mac-baibing/Desktop/去哪網(wǎng)游記Scrapy/圖集'
#ImageItem中定義的src
IMAGES_URLS_FIELD = 'src'

至此祭椰,使用srcapy爬取去哪網(wǎng)游記代碼部分完成
將所有修改的文件保存臭家,再次啟動爬蟲
結(jié)果如下


image.png

后記:過程中遇到的問題

1 response.css 和 response.xpath的使用不熟悉,可以加強
2 allowed_domains 中要將自己所有后續(xù)用到的添加進去方淤,要不然被過濾了就很尷尬钉赁,第一次處理圖片時,發(fā)現(xiàn)圖片請求沒反應(yīng)携茂,然后發(fā)現(xiàn)地址和主站地址域名不一樣
3
后續(xù)再根據(jù)學(xué)習(xí)內(nèi)容你踩,對這個再優(yōu)化升級

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子带膜,更是在濱河造成了極大的恐慌吩谦,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膝藕,死亡現(xiàn)場離奇詭異逮京,居然都是意外死亡,警方通過查閱死者的電腦和手機束莫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來草描,“玉大人览绿,你說我怎么就攤上這事∷肽剑” “怎么了饿敲?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逛绵。 經(jīng)常有香客問我怀各,道長,這世上最難降的妖魔是什么术浪? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任瓢对,我火速辦了婚禮,結(jié)果婚禮上胰苏,老公的妹妹穿的比我還像新娘硕蛹。我一直安慰自己,他們只是感情好硕并,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布法焰。 她就那樣靜靜地躺著,像睡著了一般倔毙。 火紅的嫁衣襯著肌膚如雪埃仪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天陕赃,我揣著相機與錄音卵蛉,去河邊找鬼。 笑死凯正,一個胖子當著我的面吹牛毙玻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播廊散,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼桑滩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起运准,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤幌氮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后胁澳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體该互,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年韭畸,在試婚紗的時候發(fā)現(xiàn)自己被綠了宇智。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡胰丁,死狀恐怖随橘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锦庸,我是刑警寧澤机蔗,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站甘萧,受9級特大地震影響萝嘁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扬卷,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一牙言、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邀泉,春花似錦嬉挡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至因谎,卻和暖如春基括,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背财岔。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工风皿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人匠璧。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓桐款,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夷恍。 傳聞我的和親對象是個殘疾皇子魔眨,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容