爬虫之Scrapy框架

本文详细介绍了Scrapy的基础安装、扩展错误解决,以及框架的五部分结构,包括如何创建项目、配置设置、解析响应、使用pipelines和scrapyshell的运用。通过实例演示了如何爬取糗事百科并存储数据,同时提供了常见问题的解决方案。

Scrapy框架基础知识

安装

pip install scrapy  # 我用的pycharm是2021.1.2专业版,不知道其它软件是否需要安装其他东西

扩展错误解决

安装错误解决

buliding 'twisted.test.raiser' extension error:Miscrosoft Visual C++ Bulid Tools:"http://landinghub.visualstudio.com/visual-cpp-bulid-tools

解决方案

http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted下载twisted对应版本的whl文件,(如某人的Twisted-17.5.0-cp36-cp6m-win_amd64.whl),cp后面是python版本,amd64代表64位
运行命令:
pip install 文件名  # (就是下载的文件名),我这里用的pycharm没有出现这个情况,所以我也没有验证,直接pip install scrapy就可以了。

框架介绍

框架有5部分组成:
引擎、下载器、spiders、调度器(schedule)、管道(pipline)
我们的代码写到spiders、管道中,spiders里面我们要实现文件内容解析,链接提取,管道:数据是保存到文件中、mysql中、MongDB中?
流程详解图:
在这里插入图片描述

scrapy简单使用

(1)创建项目

scrapy startproject firstblood  # firstblood为项目文件名,这条命令也可在pycharm终端写,也可以找到自己的项目以后在cmd命令窗口写,但是必须要有安装好的scrapy
cd firstblood
scrapy genspider example example.com  # example表示爬虫名(可以随便),example表示爬取的网站域名,比如命令,scrapy genspider www.baidu.com

(2)认识目录结构

firstblood
	firstblood                   # 真正的项目文件
		__pycache__              # 缓存文件(没有这个文件也没有关系)
		spiders                  # 爬虫文件存放的地方
			__pycache__          
			__init__.py
			lala.py              # 爬虫文件(*)
		__init__.py              # 包的标志
		items.py                 # 定义数据结构的地方(*)
		middlewares.py           # 中间件
		pipelines.py             # 管道文件(*)
		settings.py              # 配置文件(*)
	scrapy.cfg                   # 不用管

以糗事百科为例

  1. scrapy startproject qiushiproject
  2. cd qiushiproject
  3. scrapy genspider qiubai www.qiushibaike.com
  4. qiubai.py文件
class QiubaiSpider(scrapy.Spider):
	# 爬虫的名字
	name = 'qiubai'
	# 允许的域名,是一个列表,里面可以放多个,一般都做限制
	allowed_domains = ['www.qiushibaike.com']
	# 起始url,是一个列表
	start_urls = ['http://www.qiushibaike.com/']

	# 解析函数,重写这个方法,发送请求之后,响应来了就会调用这个方法。函数有一个参数response就是响应内容,该函数对返回值有一个要求,必须返回可迭代对象
	# 自动回调解析内容函数
	def parse(self,response):
		pass

认识response对象

  1. 让程序跑起来:
    cd firstblood/firstblood/spiders
    scrapy crawl qiubai
    (问题1)取消遵从robots协议
    settings.py中第22行注释或者把True改为False
    (问题2)修改UA头部信息
    settings.py中第19行,把User-Agent改为自己的User-Agent
  2. response的常用方法和属性
    text:字符串类型
    body:字节类型
    url:请求的url
    status:响应状态码
    headers:响应头
    xpath():scrapy内部已经集成了xpath,直接使用即可,此xpath非彼xpath,略有不同,提取出来的是selector对象,需进行extract()一下,在提取出来字符串
    css():根据选择器获取指定的内容
    例子:
    ret = response.css(’#content-left>div>.author img::attr(src)’)获取图片的src属性
    ret = response.css(’#content-left>div>.author h2::text ')获取h2的t文本属性,也需要extract()一下

执行输出指定格式

scrapy crawl qiubai -o qiyubai.json  # 以json格式输出
scrapy crawl qiubai -o qiubai.xml    # 以xml格式输出
scrapy crawl qiubai -o qiubai.csv    # 以csv格式输出
# 以csv格式输出时,中间估计有空行,自己百度自己解决

scrapy shell

  1. scrapy shell是什么:调试工具,常用来调试xpath对不对
  2. 安装依赖:pip install ipython,更加智能的交互环境,可以使用tab键智能提醒
  3. 终端下任意位置输入如下指令:scrapy shell url

selector对象

  1. 它是scrapy自己封装的一个对象,不论你是通过xpath还是css,获取到的都是这个对象
  2. 具有的方法:
    xpath()
    css()
    extract():将对象直接转化为字符串
    extract_first():功能等同于
    extract_first() == [0].extract() ==extract()[0]如果xpath或者css写错了,返回的是空列表,那么通过后面两种方式获取的时的就会报错,但是通过extract_first()来获取会获取到None

item对象

  1. 爬取数据的时候,第一步要定义数据结构,在items.py中定义,通过这个类创建的对象非常特殊,这个对象使用的时候类似字典,而且这个对象可以快速转化为字典。
  2. 例子:
class Person(scrapy.Item):
	name = scrapy.Feild()
	age = scrapy.Feild()
p = Person()
p['name'] = '张三'
p['age'] = 20
# 转化为字典
d = dict(p)

yield item和请求

  1. yeild是什么意思:函数中出现yield,代表这个函数是一个生成器,一个函数可以出现多个yield
  2. 通过scrapy来爬取糗事百科
    修改配置文件(settings.py):DOWNLOAD_DELAY=3 下载延迟
    ITEM_PIPELINES = {
    使用哪一个管道,后面的数字是优先级
    ‘firstblood.pipelines.FirstbloodPipeline’: 300,
    }

爬取糗事百科代码

items.py文件:

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

import scrapy


class FirstbloodItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 定义数据结构
    # 用户头像的url地址
    icon_url = scrapy.Field()
    # 用户名
    username = scrapy.Field()
    # 用户年龄
    age = scrapy.Field()
    # 用户发表的内容
    content = scrapy.Field()
    # 好笑的个数
    haha_count = scrapy.Field()
    # 评论数量
    coment_count = scrapy.Field()
    

qiubai.py文件:

import scrapy

from firstblood.items import FirstbloodItem


class QiubaiSpider(scrapy.Spider):
    name = 'qiubai'
    allowed_domains = ['www.qiushibaike.com']
    start_urls = ['https://www.qiushibaike.com/text/']
    page = 1
    url = 'https://www.qiushibaike.com/text/page/{}/'
    def parse(self, response):
        content_div = response.xpath('//*[@id="content"]/div/div[2]/div')
        for content_d in content_div:
            item = FirstbloodItem()
            # 头像的url地址
            icon_url = content_d.xpath('.//div/a/img/@src').extract_first()
            icon_url = 'https:'+icon_url
            # 用户名
            username = content_d.xpath('.//div/a[2]/h2/text()').extract_first().strip('\n')
            # 年龄
            age = content_d.xpath('.//div/div/text()').extract_first()
            # 内容 //*[@id="qiushi_tag_124466562"]/a[1]/div/span/text()[2]
            content = content_d.xpath('.//a[1]/div[@class="content"]/span[1]').xpath('string(.)').extract_first()
            # 好笑个数
            haha_count = content_d.xpath('.//div[2]/span[1]/i/text()').extract_first()
            # 评论个数
            comment_count = content_d.xpath('.//div[2]/span[2]/a/i/text()').extract_first()
            item['icon_url'] = icon_url
            item['username'] = username
            item['age'] = age
            item['content'] = content.strip('\n')
            item['haha_count'] =haha_count
            item['coment_count'] = comment_count
            yield item
        # 爬取多页数据
        if self.page<=5:
            self.page +=1
            url = self.url.format(self.page)
            # 向拼接成功的url发送请求
            yield scrapy.Request(url=url,callback=self.parse)

piplines.py文件:

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
import json

from itemadapter import ItemAdapter


class FirstbloodPipeline:
    # 重写这个方法,当爬虫开启的时候就会调用这个方法
    def open_spider(self,spider):
        self.fp = open('qiubai.txt','w',encoding='utf8')

    # 处理item数据的方法
    def process_item(self, item, spider):
        # 要将item保存到文件中
        # 将对象转化为字典
        dic = dict(item)
        # 将字典转化为json数据
        strin = json.dumps(dic,ensure_ascii=False)
        self.fp.write(strin+'\n')
        return item

    # 当爬虫结束时候调用这个方法
    def close_spider(self,spider):
        self.fp.close()

这里爬取糗事百科有点小问题,就是内容与之有点不对应

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值