热门搜索 :
考研考公
您的当前位置:首页正文

Scrapy学习笔记(5)-CrawlSpider+sqlalc

来源:东饰资讯网

前言

基础知识

class scrapy.spiders.CrawlSpider

这是抓取一般网页最常用的类,除了从Spider继承过来的属性外,其提供了一个新的属性rules,它提供了一种简单的机制,能够为将要爬取的链接定义一组提取规则。

rules

这是一个Rule对象列表,每条规则定义了爬取网站链接的行为,如果一条链接命中多条规则,以第一条规则进行匹配,顺序由属性中定义的顺序决定。

Link Extractors

LxmlLinkExtractor

classscrapy.linkextractors.lxmlhtml.LxmlLinkExtractor(

allow=(),

deny=(),

allow_domains=(),

deny_domains=(),

deny_extensions=None,

restrict_xpaths=(),

restrict_css=(),

tags=(‘a’, ‘area’),

attrs=(‘href’, ),

canonicalize=True,

unique=True,

process_value=None

)

参数解释:

allow 只有匹配这个正则表达式(或正则表达式列表)的URL才会被提取。如果没有给出(或None) ,它会匹配所有的链接。

deny 匹配这个正则表达式(或正则表达式列表)的URL将会被排除在外(即不提取)。它的优先级高于allow参数,如果没有给出(或None) ,将不排除任何链接。

allow_domains 包含特定域名的字符串或字符串列表,表示允许从这里面提取链接

deny_domains 包含特定域名的字符串或字符串列表, 表示不允许从这里面提取链接

deny_extensions 提取链接时,忽略扩展名的列表。如果没有给出,默认为scrapy.linkextractor模块中定义的ignored_extensions列表。

restrict_xpaths 单个xpath表达式或xpath表达式列表,若不为空,则只使用该参数去提取URL,和allow共同作用过滤链接。

restrict_css 单个css选择器或者选择器列表,作用和restrict_xpaths一样

tags 提取链接时要考虑的标签或标签列表。默认为 ( ‘a’ , ‘area’)

attrs 提取链接时应该寻找的attrbitues列表(仅在 tags 参数中指定的标签)。默认为 (‘href’)。

canonicalize 是否标准化每个提取的URL,使用w3lib.url.canonicalize_url。默认为True。

unique 是否过滤提取过的URL,布尔类型

process_value 处理tags和attrs提取到的URL的函数,它能修改并返回一个新值。如果为空则默认是lambda x: x

Rule

classscrapy.spiders.Rule(

link_extractor,

callback=None,

cb_kwargs=None,

follow=None,

process_links=None,

process_request=None

)

参数解释:

link_extractor 是一个Link Extractor对象,定义怎样提取每个需要爬取的页面中的链接。

callback 是一个可调用方法或者一个字符串(spider类中用这个字符串命名的方法)会被每个指定的link_extractor 调用,这个方法的第一个参数是response必须返回一个item或者Request的list。

cb_kwargs 是一个包含关键字参数的字典,可以传递给callback函数。

follow 是一个布尔值,指定这些通过规则匹配出来的链接是否需要继续,如果callback是None,follow默认为False,否则follow是True。

process_links是一个可调用方法或者一个字符串(spider类中用这个字符串命名的方法)会被每个指定的link_extractor调用,这个主要作用是过滤。

process_request 是一个可调用方法或者一个字符串(spider类中用这个字符串命名的方法)会被这个规则的每个request调用,必须返回一个request或者None。

SQLAlchemy

Xpath

实践

项目结构如上图所示,model目录存放数据库表的映射文件,proxy.py是目标表的映射文件,rules.py以及和model目录同级的__init__.py文件本文中暂时用不到先不管,其他文件都是本次实践需要用到的。

1.items.py

2.model目录下的__init__.py

# -*- coding: utf-8 -*-from sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmaker# 创建对象的基类:Base = declarative_base()# 初始化数据库连接:engine = create_engine('mysql+mysqldb://root:123456@localhost:3306/scrapy?charset=utf8')#返回数据库会话def loadSession():    Session = sessionmaker(bind=engine)    session = Session()    return session

3.proxy.py(数据库表proxies的映射文件)

# -*- coding: utf-8 -*-from sqlalchemy import Column,String,Integer,DateTimefrom . import Baseimport datetimeclass Proxy(Base):    __tablename__ = 'proxies'    ip_port=Column(String(30),primary_key=True,nullable=False)    type=Column(String(20),nullable=True)    level=Column(String(20),nullable=True)    location=Column(String(100),nullable=True)    speed=Column(Integer,nullable=True)    source = Column(String(500), nullable=False)    indate=Column(DateTime,nullable=False)    def __init__(self,ip_port,source,type=None,level=None,location=None,speed=None):        self.ip_port=ip_port

        self.type=type

        self.level=level

        self.location=location

        self.speed=speed

        self.source=source

        self.indate=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

4.pipelines.py

5.proxy_spider.py

        item=IpProxyPoolItem()        for proxy in response.xpath("//table[@class='list']/tr[position()>1]"):            ip=proxy.xpath("td[1]/text()").extract_first()            port=proxy.xpath("td[2]/text()").extract_first()            location1=proxy.xpath("td[3]/a[1]/text()").extract_first()            location2=proxy.xpath("td[3]/a[2]/text()").extract_first()            level=proxy.xpath("td[4]/text()").extract_first()            type = proxy.xpath("td[5]/text()").extract_first()            speed=proxy.xpath("td[6]/text()").extract_first()            item['ip_port']=(ip if ip else "")+":"+(port if port else "")            item['type']=(type if type else "")            item['level']=(level if level else "")            item['location']=(location1 if location1 else "")+" "+(location2 if location2 else "")            item['speed']=(speed if speed else "")            item['source']=response.url

            return item

6.settings.py

# -*- coding: utf-8 -*-# Scrapy settings for ip_proxy_pool projectBOT_NAME = 'ip_proxy_pool'SPIDER_MODULES = ['ip_proxy_pool.spiders']NEWSPIDER_MODULE = 'ip_proxy_pool.spiders'# Obey robots.txt rulesROBOTSTXT_OBEY = TrueITEM_PIPELINES = {  'ip_proxy_pool.pipelines.IpProxyPoolPipeline': 300,}DOWNLOAD_DELAY = 2

7.运行spider,查看结果

shell中执行scrapy crawl proxy_spider,发现数据库中已经自动生成了表proxies并且数据已经入库,Done!

更多原创文章,尽在

Top