1. 程式人生 > 其它 >爬蟲入門 03 Scrapy框架初步使用

爬蟲入門 03 Scrapy框架初步使用

1.首先了解一下Scrapy框架:

1.1官網的描述

An open source and collaborative framework for extracting the data you need from websites.
1.開源的爬蟲框架
In a fast, simple, yet extensible way.
2.快速、簡單、高效的方式

1.2安裝部署

pip install scrapy

2.基本使用

1.建立專案(想在哪個檔案目錄下建立就切換到哪個目錄)

PS D:\ \python-sk> scrapy startproject homeworkPS
專案目錄:
1.scrapy.cfg 【專案的配置檔案】
2.settings.py 【專案的配置檔案】
3. spiders/ 【防止 爬蟲程式碼的目錄】

2.編寫爬蟲程式碼

2.1建立爬蟲程式碼

scrapy genspider [options]
示例如下(一定要切換到spiders目錄再建立)

2.2建立一個Python爬蟲檔案,python01.py

PS D:\ \python-sk> cd .\homework
PS D:\ \python-sk\homework> cd .\homework
PS D:\ \python-sk\homework\homework> cd .\spiders
PS D:\ \python-sk\homework\homework\spiders> scrapy genspider python01

https://dl.58.com/cat

2.3python01.py引數說明

name:
    1.不能重複
    2.爬蟲檔案的名字
'''
name = 'python01'
'''
   scrapy 允許爬取的 url 
'''
allowed_domains = ['www.baidu.com']
'''
    scrapy 去爬取的 url 列表
'''
start_urls = ['[http://www.baidu.com/','https://www.sougou.com']](http://www.baidu.com/','https://www.sougou.com'])

2.4.在sittings.py檔案中加上如下引數,來模擬請求和轉碼

指定字符集

FEED_EXPORT_ENCODING = 'UTF8'

指定控制檯輸出日誌的等級,不然輸出一大堆

LOG_LEVEL = 'ERROR'

指定USER_AGENT,這個一定要指定,不然會被封

USER_AGENT = '你的ua'

3.啟動專案

3.1啟動命令說明

scrapy runspider [options] <spider_file>
scrapy runspider ./test_scrapy/spiders/python01.py
scrapy crawl python01
scrapy crawl python01 --nolog 【使用命令 不顯示日誌資訊】

3.2啟動命令使用(一定要在專案的目錄下,否則無法使用命令)

PS D:\ \python-sk\homework> scrapy crawl python01
<200 https://dl.58.com/cat/>

3.3資料解析

標籤定位

只支援原生html的標籤,像什麼tbody一概不支援
返回 selector(xpath,data[xpath表示式 結果])

資料解析

返回 selector(xpath,data[xpath表示式 結果])
.extract()方法(得到Selector裡面的data,不要xpath)
normalize-space(xxx)(去掉字元裡的\t\r\n等資料)
取值
.get()
.getall()

資料儲存

外層定義一個list[],裡層用dict寫
scrapy crawl python01 -o ./chongwu.json 【不支援txt格式】

4.案例

案例1,爬取三國小說

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

class Python01Spider(scrapy.Spider):
    '''
        name:
            1.不能重複
            2.爬蟲檔案的名字
    '''
    name = 'python01'
    '''
        scrapy 允許爬取的 url , 引數可以暫時關閉scrapy crawl
    '''
    #allowed_domains = ['www.baidu.com']
    '''
        scrapy 去爬取的url 列表
    '''
    start_urls = ['https://www.shicimingju.com/book/sanguoyanyi.html']

    def parse(self, response):

        # 使用cls清理cmd螢幕

        # print(response)
        '''
        省略etree
        scrapy資料解析 =》
            1.標籤定位:
               返回selector(xpath,data[xpath表示式 結果])
            2.資料解析
               返回selector(xpath,data[xpath表示式 結果])
            3.取值

        '''
        li_list = response.xpath('//div[@class = "book-mulu"]/ul/li')

        # print(li_list)
        res = []
        for key,li in enumerate(li_list):
            '''
            a_text = li.xpath('./a/text()')
            print(a_text)
            '''

            # 取值的第一個方法,只取一個
            a_text_get = li.xpath('./a/text()').get()

            # 也可以在settings裡面新增引數
            # settings裡新增引數,LOG_LEVEL = 'ERROR'設定log級別
            # a_text_get.encode('utf-8').decode('unicode_escape')

            dic = {
                'id':key,
                'title':a_text_get
            }

            res.append(dic)

            # print(a_text1)

            '''
            # 取值的第二個方法,取所有的,返回列表
            a_text2 = li.xpath('./a/text()').getall()
            print(a_text2)
            '''
        return res

案例2,爬取58同城寵物資料【全是坑】

import scrapy


class Python01Spider(scrapy.Spider):
    name = 'python01'
    # allowed_domains = ['dl.58.com']
    start_urls = ['https://dl.58.com/cat']

    def parse(self, response):
        # print(response.request.headers["User-Agent"])
        print(response)

        list = response.xpath('//div[@id="main"]/div[@id="infolist"]/table')
        # 用於持久儲存
        res = []
        # print(list)
        for li in list:
            '''
            踩坑日記
            這種title資料沒眼看
            ['\r\n           \t\t\t\t\t種公貓借配 800-1000\r\n           \t\t\t\t''\r\n           \t\t\t\t\t種公貓借配 800-1000\r\n           \t\t\t\t'
            所以採用
            # 'normalize-space(xxx)'可以去掉字元裡的\t\t\t\t\t等等
            # title = li.xpath('normalize-space(./tr/td[@class="t"]/a/text())'),只輸出一個,所以下面採用for迴圈
            得到
            ['種公貓借配 800-1000', '鞍山高價收購寵物貓 幼貓成貓長期批發零售擁有實體店', '金漸層 銀漸層 銀點 布偶 美短 小崽出售 底價!']
            實現程式碼如下
            '''
            # 使用.extract()方法提取選中的內容
            # 使用normalize-space(xxx)來去掉字元裡的\t\t\t\t\t等等
            title = li.xpath('./tr/td[@class="t"]/a')
            messagelist = []
            for ti in title:
                temp = ti.xpath('normalize-space(./text())').extract()
                messagelist.append(temp[0])
            # 資料規範化,但是58坑城資料是三個一組的
            # print(messagelist)
            '''
            這個price資料還能看,不用規範化
            ['1000', '1000', '1000']
            實現程式碼如下
            '''
            # 使用extract()方法提取選中的內容
            price = li.xpath('./tr/td[@class="pd"]/b/text()').extract()
            # print(price)

            '''
            得到價格陣列,但是58坑城資料是三個一組的
            所以要使用for來持久化,在外面定義一個res,然後往裡寫dict
            '''
            for key,message in enumerate(messagelist):
                # print("000")
                dic = {
                    'id': key,
                    'title': " 資訊:" + message +"  售價:" +price[key]
                }
                res.append(dic)
        print("資料爬取完畢")
        return res