爬虫入门之Scrapy框架基础框架结构及腾讯爬取(十)

简介: Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取的数据。

Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取的数据。

如果安装了 IPython ,Scrapy终端将使用 IPython (替代标准Python终端)。 IPython 终端与其他相比更为强大,提供智能的自动补全,高亮输出,及其他特性。(推荐安装IPython)

1 启动Scrapy Shell

进入项目的根目录,执行下列命令来启动shell:

scrapy shell "https://hr.tencent.com/position.php?&start=0#a"

Scrapy Shell根据下载的页面会自动创建一些方便使用的对象,例如 Response 对象,以及Selector 对象 (对HTML及XML内容)

  • 当shell载入后,将得到一个包含response数据的本地 response 变量,输入response.body将输出response的包体,输出response.headers可以看到response的包头。
  • 输入response.selector时, 将获取到一个response 初始化的类 Selector 的对象,此时可以通过使用response.selector.xpath()response.selector.css()来对 response 进行查询。
  • Scrapy也提供了一些快捷方式, 例如response.xpath()response.css()同样可以生效(如之前的案例)。

2 Selectors选择器

Scrapy Selectors 内置 XPath 和 CSS Selector 表达式机制

Selector有四个基本的方法,最常用的还是xpath:

  • xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表
  • extract(): 序列化该节点为Unicode字符串并返回list
  • css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表,语法同 BeautifulSoup4
  • re(): 根据传入的正则表达式对数据进行提取,返回Unicode字符串list列表
response.xpath('//title')

3 Item Pipeline

当Item在Spider中被收集之后,它将会被传递到Item Pipeline,这些Item Pipeline组件按定义的顺序处理Item。

每个Item Pipeline都是实现了简单方法的Python类,比如决定此Item是丢弃而存储。以下是item pipeline的一些典型应用:

  • 验证爬取的数据(检查item包含某些字段,比如说name字段)
  • 查重(并丢弃)
  • 将爬取结果保存到文件或者数据库中

编写item pipeline很简单,item pipiline组件是一个独立的Python类,其中process_item()方法必须实现:

import something

class SomethingPipeline(object):
    def __init__(self):    
        # 可选实现,做参数初始化等
        # doing something

    def process_item(self, item, spider):
        # item (Item 对象) – 被爬取的item
        # spider (Spider 对象) – 爬取该item的spider
        # 这个方法必须实现,每个item pipeline组件都需要调用该方法,
        # 这个方法必须返回一个 Item 对象,被丢弃的item将不会被之后的pipeline组件所处理。
        return item

    def open_spider(self, spider):
        # spider (Spider 对象) – 被开启的spider
        # 可选实现,当spider被开启时,这个方法被调用 (也可以放在__init__方法中)

    def close_spider(self, spider):
        # spider (Spider 对象) – 被关闭的spider
        # 可选实现,当spider被关闭时,这个方法被调用 (也可放入析构函数__del__方法中)

Pipeline实现文件的写入打开操作

以下pipeline将所有(从所有’spider’中)爬取到的item,存储到一个独立地txt文件

class TianyaPipeline(object):
    def __init__(self):
        self.f = open("tianya.txt", "w", encoding="utf-8")
    def process_item(self, item, spider):
        self.f.write(str(item))
        # return item
    def __del__(self):
        self.f.close()
#附Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
#replace用于替换指定字符
#join用于合并列表 元组等

启用一个Item Pipeline组件

为了启用Item Pipeline组件,必须将它的类添加到 settings.py文件ITEM_PIPELINES 配置,就像下面这个例子:

ITEM_PIPELINES = {
   'tianya.pipelines.TianyaPipeline': 300,
}

分配给每个类的整型值,确定了他们运行的顺序,item按数字从低到高的顺序,通过pipeline,通常将这些数字定义在0-1000范围内(0-1000随意设置,数值越低,组件的优先级越高)

4 Spider

Spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。

class scrapy.Spider是最基本的类,所有编写的爬虫必须继承这个类。

主要用到的函数及调用顺序为:

__init__(): 初始化爬虫名字和start_urls列表

start_requests() 调用make_requests_from url():生成Requests对象交给Scrapy下载并返回response

parse(): 解析response,并返回Item或Requests(需指定回调函数)。Item传给Item pipline持久化 , 而Requests交由Scrapy下载,并由指定的回调函数处理(默认parse()),一直进行循环,直到处理完所有的数据为止。

源码参考

#所有爬虫的基类,用户定义的爬虫必须从这个类继承
class Spider(object_ref):

    #定义spider名字(string)。spider的名字定义了Scrapy如何定位(并初始化)spider,所以其必须是唯一的。
    #name是spider最重要的属性,而且是必须的。
    #一般做法是以该网站(domain)(加或不加 后缀 )来命名spider。例如,爬取百度命名为: baidu
    name = None

    #初始化,提取爬虫名字,start_ruls
    def __init__(self, name=None, **kwargs):
        if name is not None:
            self.name = name
        # 如果爬虫没有名字,中断后续操作则报错
        elif not getattr(self, 'name', None):
            raise ValueError("%s must have a name" % type(self).__name__)

        # python 对象或类型通过内置成员__dict__来存储成员信息
        self.__dict__.update(kwargs)

        #URL列表。当没有指定的URL时,spider将从该列表中开始进行爬取。 
        #因此,第一个被获取到的页面的URL将是该列表之一。后续的URL将会从获取到的数据中提取。
        if not hasattr(self, 'start_urls'):
            self.start_urls = []

    # 打印Scrapy执行后的log信息
    def log(self, message, level=log.DEBUG, **kw):
        log.msg(message, spider=self, level=level, **kw)

    # 判断对象object的属性是否存在,不存在做断言处理
    def set_crawler(self, crawler):
        assert not hasattr(self, '_crawler'), "Spider already bounded to %s" % crawler
        self._crawler = crawler

    @property
    def crawler(self):
        assert hasattr(self, '_crawler'), "Spider not bounded to any crawler"
        return self._crawler

    @property
    def settings(self):
        return self.crawler.settings

    #该方法将读取start_urls内的地址,并为每一个地址生成一个Request对象,交给Scrapy下载并返回Response
    #该方法仅调用一次
    def start_requests(self):
        for url in self.start_urls:
            yield self.make_requests_from_url(url)

    #start_requests()中调用,实际生成Request的函数。
    #Request对象默认的回调函数为parse(),提交的方式为get
    def make_requests_from_url(self, url):
        return Request(url, dont_filter=True)

    #默认的Request对象回调函数,处理返回的response。
    #生成Item或者Request对象。用户必须实现这个类
    def parse(self, response):
        raise NotImplementedError

    @classmethod
    def handles_request(cls, request):
        return url_is_from_spider(request.url, cls)

    def __str__(self):
        return "<%s %r at 0x%0x>" % (type(self).__name__, self.name, id(self))

    __repr__ = __str__

主要属性和方法

  • name

    定义spider名字的字符串。

    例如,如果spider爬取 mywebsite.com ,该spider通常会被命名为 mywebsite

  • allowed_domains

    包含了spider允许爬取的域名(domain)的列表,可选。

  • start_urls

    初始URL元祖/列表。当没有制定特定的URL时,spider将从该列表中开始进行爬取。

  • start_requests(self)

    该方法必须返回一个可迭代对象(iterable)。该对象包含了spider用于爬取(默认实现是使用 start_urls 的url)的第一个Request。

    当spider启动爬取并且未指定start_urls时,该方法被调用。

  • parse(self, response)

    当请求url返回网页没有指定回调函数时,默认的Request对象回调函数。用来处理网页返回的response,以及生成Item或者Request对象。

  • log(self, message[, level, component])

    使用 scrapy.log.msg() 方法记录(log)message。 更多数据请参见logging

5 案例:腾讯招聘网自动翻页采集

  • 创建一个新的爬虫:

scrapy genspider tencent "tencent.com"

  • 编写items.py

获取职位名称、详细信息、

class TencentItem(scrapy.Item):
    # 定义需要爬取的字段
    jobTitle = scrapy.Field()
    jobCategories = scrapy.Field()
    number = scrapy.Field()
    location = scrapy.Field()
    releasetime = scrapy.Field()
  • 编写tencent.py
# -*- coding: utf-8 -*-
import re
import scrapy
from Tencent import items

class MytencentSpider(scrapy.Spider):
    name = 'myTencent'
    allowed_domains = ['hr.tencent.com']
    start_urls = ['https://hr.tencent.com/position.php?lid=2218&start=0#a']

    def parse(self, response):
        for data in response.xpath("//tr[@class=\"even\"] | //tr[@class=\"odd\"]"):
            item = items.TencentItem()
            item["jobTitle"] = data.xpath("./td[1]/a/text()")[0].extract()
            item["jobLink"] = data.xpath("./td[1]/a/@href")[0].extract()
            item["jobCategories"] = data.xpath("./td[1]/a/text()")[0].extract()
            item["number"] = data.xpath("./td[2]/text()")[0].extract()
            item["location"] = data.xpath("./td[3]/text()")[0].extract()
            item["releasetime"] = data.xpath("./td[4]/text()")[0].extract()
            yield item

            for i in range(1, 200):
                newurl = "https://hr.tencent.com/position.php?lid=2218&start=%d#a" % (i*10)
                yield scrapy.Request(newurl, callback=self.parse)
  • 编写pipeline.py文件
class TencentPipeline(object):
    def __init__(self):
        self.file = open("tencent.txt", "w", encoding="utf-8")  #初始化即打开

    def process_item(self, item, spider):
        line = str(item) + "\r\n"
        self.file.write(line)
        self.file.flush()
        return item

    def __del__(self):  #数据清除时关闭
        self.file.close()
  • 在 setting.py 里设置ITEM_PIPELINES
ITEM_PIPELINES = {
    "mySpider.pipelines.TencentJsonPipeline":300
}
  • 执行爬虫:

    scrapy crawl tencent.py

相关文章
|
3天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
24 6
|
4天前
|
数据采集 前端开发 中间件
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第26天】Python是一种强大的编程语言,在数据抓取和网络爬虫领域应用广泛。Scrapy作为高效灵活的爬虫框架,为开发者提供了强大的工具集。本文通过实战案例,详细解析Scrapy框架的应用与技巧,并附上示例代码。文章介绍了Scrapy的基本概念、创建项目、编写简单爬虫、高级特性和技巧等内容。
21 4
|
3天前
|
数据采集 中间件 API
在Scrapy爬虫中应用Crawlera进行反爬虫策略
在Scrapy爬虫中应用Crawlera进行反爬虫策略
|
28天前
|
消息中间件 数据采集 数据库
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
18 1
|
24天前
|
数据采集 监控 中间件
Scrapy入门到放弃03:理解settings配置,监控scrapy引擎|8月更文挑战
Scrapy入门到放弃03:理解settings配置,监控scrapy引擎|8月更文挑战
|
3月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
157 4
|
3月前
|
数据采集 存储 搜索推荐
打造个性化网页爬虫:从零开始的Python教程
【8月更文挑战第31天】在数字信息的海洋中,网页爬虫是一艘能够自动搜集网络数据的神奇船只。本文将引导你启航,用Python语言建造属于你自己的网页爬虫。我们将一起探索如何从无到有,一步步构建一个能够抓取、解析并存储网页数据的基础爬虫。文章不仅分享代码,更带你理解背后的逻辑,让你能在遇到问题时自行找到解决方案。无论你是编程新手还是有一定基础的开发者,这篇文章都会为你打开一扇通往数据世界的新窗。
|
4月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
【7月更文挑战第31天】在网络数据的海洋中,使用Python的`requests`库构建网络爬虫就像探索未知的航船。HTTP协议指导爬虫与服务器交流,收集信息。HTTP请求包括请求行、头和体,响应则含状态行、头和体。`requests`简化了发送各种HTTP请求的过程。
80 4
|
1月前
|
数据采集 存储 数据挖掘
深入探索 Python 爬虫:高级技术与实战应用
本文介绍了Python爬虫的高级技术,涵盖并发处理、反爬虫策略(如验证码识别与模拟登录)及数据存储与处理方法。通过asyncio库实现异步爬虫,提升效率;利用tesseract和requests库应对反爬措施;借助SQLAlchemy和pandas进行数据存储与分析。实战部分展示了如何爬取电商网站的商品信息及新闻网站的文章内容。提醒读者在实际应用中需遵守法律法规。
158 66
|
1天前
|
数据采集 Web App开发 JavaScript
爬虫策略规避:Python爬虫的浏览器自动化
爬虫策略规避:Python爬虫的浏览器自动化