3.Scrapy 入門案例

一 【學(xué)習(xí)目標】

  • 創(chuàng)建一個Scrapy項目
  • 定義提取的結(jié)構(gòu)化數(shù)據(jù)Item
  • 編寫爬蟲網(wǎng)頁的Spider并提取出結(jié)構(gòu)化數(shù)據(jù)Item
  • 編寫Item Pipelines 來存儲提取的Item數(shù)據(jù)(可以存儲到MySQL或Redis)

二 【新建一個新的項目】

  1. 新建一個項目,并進入項目目錄陪拘。
scrapy startproject mySpider
cd mySpider
image.png

項目中文件的作用:

  • scrapy.cfg : 項目的配置文件
  • mySpider:項目的模塊槐瑞,放項目相關(guān)的代碼文件
  • mySpider/items.py:項目的數(shù)據(jù)機構(gòu)存儲文件
  • mySpider/pipelines.py:項目的管道文件
  • mySpider/settings.py:項目的設(shè)置文件
  • mySpider/spiders:放置爬蟲程序的目錄,多個爬蟲就多個子目錄

三【設(shè)置數(shù)據(jù)結(jié)構(gòu)】
這里我打算取的地址是:
http://www.dytt8.net/html/gndy/dyzz/list_23_1.html
獲取所有電影的標題区赵、鏈接愉烙、描述和下載地址

  1. 打開mySpider目錄下的Items.py

  2. 定義電影的結(jié)構(gòu)化數(shù)據(jù)的字段减牺,用于保存獲取到的數(shù)據(jù)页徐。

  3. 可以通過創(chuàng)建一個scrapy Item 類苏潜,并且類型為Scrapy.Field來定義一個Item。

4.下面我們創(chuàng)建一個MyspiderItem和構(gòu)建Item的屬性变勇。

import scrapy


class MyspiderItem(scrapy.Item):
    # define the fields for your item here like:
    title = scrapy.Field()
    link = scrapy.Field()
    desc = scrapy.Field()
    download_url = scrapy.Field()
    pass

四【制作爬蟲】
1.創(chuàng)建一個爬蟲文件

scrapy genspider movie www.dytt8.net

2.修改spider/movie.py 文件,內(nèi)容如下:

# -*- coding: utf-8 -*-
import scrapy


class MovieSpider(scrapy.Spider):
    name = 'movie'
    allowed_domains = ['www.dytt8.net']
    start_urls = ['http://www.dytt8.net/']

    def parse(self, response):
        pass

這個文件也可以手動創(chuàng)建恤左,用命令比較方便一些。

  • name : 這個是爬蟲的名稱搀绣,必須唯一飞袋。

  • allow_domains : 是允許的域名范圍,是一個列表類型链患,可以設(shè)置多個域名巧鸭,表示爬蟲只能爬取允許域名下URL。

  • start_urls : 爬蟲從這里定義的URL開始爬取網(wǎng)頁麻捻。

  • parse(self,response) : 爬取網(wǎng)頁后纲仍,使用這個方法來處理爬取后獲取的網(wǎng)頁內(nèi)容。
    a. 提取頁面數(shù)據(jù)組裝結(jié)構(gòu)化數(shù)據(jù)Item
    b.獲取下一個需要爬取的URL

3.在start_urls里加入一個需要爬取的url地址

start_urls = ['http://www.dytt8.net/html/gndy/dyzz/index.html']
  1. 修改parse方法
def parse(self, response):
        with open("movie_items.html","w") as fp:
            fp.write(response.text)
        pass

5.運行一下items爬蟲

scrapy crawl movie

會生成movie_items.html頁面

  1. 取結(jié)構(gòu)化數(shù)據(jù)
    一般使用xpath,教程參考:http://www.w3school.com.cn/xpath/index.asp
    修改movie.py爬蟲文件
# -*- coding: utf-8 -*-
import scrapy
from mySpider.items import MyspiderItem
import json
import time
import time
class MovieSpider(scrapy.Spider):
    name = 'movie'
    page = 1
    base_url = "http://www.dytt8.net"
    list_base_url = base_url + '/html/gndy/dyzz/list_23_'
    allowed_domains = ['www.dytt8.net']
    start_urls = [list_base_url + "%s.html" % page]
    #電影列表回調(diào)方法
    def parse(self, response):
        #通過xpath獲取電影列表
        titlelist = response.xpath('//table[@class="tbspan"]')
        for movie in titlelist:
            item = MyspiderItem()
            title = movie.xpath("./tr[2]/td[2]/b/a/text()").extract() #通過子節(jié)點提取標題
            link = movie.xpath("./tr[2]/td[2]/b/a/@href").extract()#通過子節(jié)點提取詳情url
            desc = movie.xpath("./tr[4]/td/text()").extract() #通過子節(jié)點提取電影描述
            item['title'] = title[0] #提取后是一個只有一個元素的列表類型芯肤,所以提取第0個元素
            item['link'] = self.base_url + link[0]
            item['desc'] = desc[0]
            item['download_url'] = ''
            yield item
            #通過 item['link'] 屬性獲取詳情頁巷折,處理方法為self.parse_detail
            yield scrapy.Request(item['link'],callback=self.parse_detail)

        #繼續(xù)爬取下一頁以及后面的頁面,一共3頁
        if self.page < 3:
            self.page = self.page + 1
            page_url = self.list_base_url + "%s.html" % self.page
            print("---------------------------page number url ----------------------------")
            print(page_url)
            yield scrapy.Request(page_url, callback=self.parse)

    # 電影詳情回調(diào)方法
    def parse_detail(self,response):
        time.sleep(2)
        #通過xpath獲取電影詳情里的下載地址
        download_url = response.xpath('//*[@id="Zoom"]//table[1]//td/a/@href').extract()
        print("---------------------------detail download_url----------------------------")
        print("---------------------------" + download_url[0] + "----------------------------")
        item = MyspiderItem()
        item['link'] = response.url
        item['download_url'] = download_url[0]
        return item

  1. 保存數(shù)據(jù)
    創(chuàng)建表:
DROP TABLE IF EXISTS `movies`;
CREATE TABLE `movies` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(50) NOT NULL DEFAULT '',
  `link` varchar(200) NOT NULL DEFAULT '',
  `desc` varchar(1024) NOT NULL DEFAULT '',
  `download_url` varchar(500) DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `link` (`link`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

然后修改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 json
import pymysql
import redis
import jieba
from collections import Counter

class MyspiderPipeline(object):
    def __init__(self):
        self.id = 1;
        #鏈接數(shù)據(jù)庫
        self.db = pymysql.connect("localhost", "root", "root", "test", charset='utf8')
        #獲取游標
        self.cursor = self.db.cursor()
        #鏈接redis
        self.redisClient = redis.Redis(host="127.0.0.1", port=6379)

    def process_item(self, item, spider):
        dictitem = dict(item)
        #通過download_url判斷,如果是詳情頁獲取的item崖咨,把獲取到的電影下載地址download_url更新到mysql數(shù)據(jù)庫
        if dictitem['download_url']:
            link = dictitem['link']
            download_url = dictitem['download_url']
            sql = "UPDATE movies SET `download_url` = '%s' WHERE `link` = '%s'" \
                  % (download_url, link)
            self.cursor.execute(sql)
        # 如果是電影列表獲取的item锻拘,把獲取到的title,link,desc插入到mysql數(shù)據(jù)庫
        else:
            title = dictitem['title']
            link = dictitem['link']
            desc = dictitem['desc']
            sql = "INSERT INTO movies(`title`,`link`,`desc`) \
                                                       VALUES ('%s', '%s', '%s')" % \
                  (title, link, desc)
            self.cursor.execute(sql)
            last_id = self.cursor.lastrowid #獲取最后一次插入的主鍵id
            #用jieba對title進行分詞,把分詞和結(jié)果和主鍵的保存到redis的set數(shù)據(jù)類型里击蹲,用于搜索
            data = jieba.cut(title)
            data = dict(Counter(data))
            for k, v in data.items():#循環(huán)所有分詞
                word = k.encode('utf-8')
                self.redisClient.sadd(word, last_id)#保存每個分詞和id的對應(yīng)關(guān)系

        print("--------------------------- process_item sql ----------------------------")
        print(sql)
        self.db.commit()
        return item

需要安裝第三方模塊:

pip install pymysql
pip install redis
pip install jieba
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末署拟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子歌豺,更是在濱河造成了極大的恐慌推穷,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件类咧,死亡現(xiàn)場離奇詭異馒铃,居然都是意外死亡,警方通過查閱死者的電腦和手機痕惋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門区宇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人值戳,你說我怎么就攤上這事议谷。” “怎么了堕虹?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵卧晓,是天一觀的道長芬首。 經(jīng)常有香客問我,道長逼裆,這世上最難降的妖魔是什么郁稍? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮波附,結(jié)果婚禮上艺晴,老公的妹妹穿的比我還像新娘。我一直安慰自己掸屡,他們只是感情好封寞,可當(dāng)我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仅财,像睡著了一般狈究。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盏求,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天抖锥,我揣著相機與錄音,去河邊找鬼碎罚。 笑死磅废,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的荆烈。 我是一名探鬼主播拯勉,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼憔购!你這毒婦竟也來了宫峦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤玫鸟,失蹤者是張志新(化名)和其女友劉穎导绷,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屎飘,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡妥曲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了钦购。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片檐盟。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肮雨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情箱玷,我是刑警寧澤怨规,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布陌宿,位于F島的核電站,受9級特大地震影響波丰,放射性物質(zhì)發(fā)生泄漏壳坪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一掰烟、第九天 我趴在偏房一處隱蔽的房頂上張望爽蝴。 院中可真熱鬧,春花似錦纫骑、人聲如沸蝎亚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽发框。三九已至,卻和暖如春煤墙,著一層夾襖步出監(jiān)牢的瞬間梅惯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工仿野, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铣减,地道東北人。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓脚作,卻偏偏與公主長得像葫哗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鳖枕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,509評論 2 348

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