爬虫入门 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
posted @ 2022-04-05 21:41  咸鱼QwQ  阅读(113)  评论(0)    收藏  举报