Scrapy爬蟲簡單實例

第一個Scrapy框架爬蟲

我要爬取的網站是一個網課網站http://www.itcast.cn/channel/teacher.shtml,爬取內容是所有老師的基本信息。

1.創建一個基於Scrapy框架的爬蟲項目

進入自定義的項目目錄中,運行下列命令:

**ITCast爲項目名字**
scrapy startproject ITCast     
2. 結構化所獲取數據字段

打開項目目錄找到items.py,這個模塊,我覺得就像java中的對象實體類的定義,但是所有類都必須是scrapy.Item的子類,這裏我定義一個ItCastItem類,用於保存每一位老師的基本信息。

import scrapy


class ItCastItem(scrapy.Item):
    name = scrapy.Field() # 教師名字
    title = scrapy.Field()# 教師職稱
    info = scrapy.Field() # 教師履歷
3.製作爬蟲

1.我們必須創建一個爬蟲(可以在pycharm下的terminal下輸入該命令)

scrapy genspider itcast "itcast.cn"

創建的爬蟲會自動生成在你的項目的spiders目錄下,並且自動生成文件itcast .py,裏面還自動添加了一些基本代碼
每個爬蟲都強制要求擁有三個屬性

  • name :爬蟲的名字,由常見爬蟲的時候指定
  • allowed_domains:是搜索的域名範圍,即爬蟲的作用域,一般指定該域名之後,爬蟲則只會爬取該域名下的網頁,不存在的URL將會被忽略
  • start_urls:爬取的URL元祖/列表。爬蟲從這裏開始抓取數據,所以,第一次下載的數據將會從這些urls開始。其他子URL將會從這些起始URL中繼承性生成。

2.修改parse()方法,解析頁面數據

# -*- coding: utf-8 -*-
import scrapy
from ITCast.items import ItCastItem
from lxml import etree

class ItCastSpider(scrapy.Spider):
    name = 'itcast' # 這個爬蟲的識別名稱,必須是唯一的,在不同的爬蟲必須定義不同的名字。
    allowed_domains = ['itcast.cn'] # 是搜索的域名範圍,也就是爬蟲的約束區域,規定爬蟲只爬取這個域名下的網頁,不存在的URL會被忽略。
    start_urls = ['http://www.itcast.cn/channel/teacher.shtml'] # 爬取的URL元祖/列表。爬蟲從這裏開始抓取數據,所以,第一次下載的數據將會從這些urls開始

    # 解析的方法
    def parse(self, response):
        '''
        解析返回的網頁數據(response.body),提取結構化數據(生成item)
        :param response:
        :return:
        '''

        print(response.body)
        filename = "teacher.html"
        with open(filename,'wb') as f:
            f.write(response.body)
        context = response.xpath('/html/head/title/text()')
        # print(context)
        # 提取網站標題
        title = context.extract_first()
        print(title)

        
        html = etree.HTML(response.text)
        print("===============\n\n\n\n\n\n")
        #print(text.xpath("//div[@class='li_txt']"))
        print("===============\n\n\n\n\n\n")
        items = []  # 存放老師信息對象的列表
        # print(response.xpath("//div[@class='li_txt'][1]"))
        # print(html.xpath("//div[@class='li_txt']"))
        # 獲取每一個教師對象,進行封裝
        for each in html.xpath("//div[@class='li_txt']"):
            # 將得到的數據封裝到一個'ItcastItem'對象中
            item = ItCastItem()
            name = each.xpath(".//h3/text()")
            title = each.xpath(".//h4/text()")
            info = each.xpath(".//p/text()")
            # 封裝,xpath返回的是包含一個元素的列表,所以用name[0]
            item['name'] = name[0]
            item['title'] = title[0]
            item['info'] = info[0]

            items.append(item)
        # 返回結果集
        return items


5.運行爬蟲並保存數據

運行爬蟲有簡單的主要幾種方式模式(還有其他的沒列出來

scrapy crawl itcast                        //單純的運行爬蟲,結果會在終端打印出來
scrapy crawl itcast -o teachers.json  	   //運行蟲,並保存爲json文件數據格式
scrapy crawl itcast -o teachers.jsonlines  //運行爬蟲,並保存爲jsonlines文件數據格式
scrapy crawl itacst -o teachers.csv        //運行爬蟲,並保存爲csv文件數據格式(可以使用Excel打開)
scrapy crawl itcast -o teachers.xml  	   //運行爬蟲,並保存爲xml文件數據格式
6.查看結果

回到項目目錄可以看到已經生成的文件,給大家看一下我的項目目錄和生成的文件
在這裏插入圖片描述
在這裏插入圖片描述

7. 錯誤總結

解析頁面的時候,總是不能正確的拿到數據,每次拿到的數據都是空列表,因此用了chropath插件慢慢的在谷歌瀏覽器嘗試,後來才發現,原來是在獲取每個item的info,name,title的時候,使用錯了xpath。
錯誤的)我之前填寫的是:

 name = each.xpath("//h3/text()")
 title = each.xpath("//h4/text()")
 info = each.xpath("//p/text()")

這裏的each是網頁中的每一位教師的div外框,因此我想通過這種方式,然後直接獲取該div下的第一個h3,h4 , p標籤,但是一直獲取的都是錯誤數據
我查詢錯誤數據來源,發現竟然是頁面的第一個h3,h4 , p標籤的內容,我頓時醒悟。
正確的)應該是這樣:

 name = each.xpath("./h3/text()")
 title = each.xpath(".//h4/text()")
 info = each.xpath(".//p/text()")

加個點後,就是取當前元素的子元素,否則它就從最開始查找了。

要是有些地方不對,請大家幫忙指出哦,歡迎大家留言。
一起共勉!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章