上一篇简单了解了scrapy各个模块的功能:Scrapy框架初探 -- Dapianzi卡夫卡

在这篇通过一些实例来深入理解 scrapy 的各个对象以及它们是怎么相互协作的

settings.py 配置文件

#USER_AGENT = 'cats (+http://www.yourdomain.com)'
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36' # Obey robots.txt rules 是否乖乖听从robot.txt
#ROBOTSTXT_OBEY = True # Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32 # Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs 请求间隔时间。需要看抓取时间需求,IP资源,目标网站反爬虫策略
DOWNLOAD_DELAY = 1
# The download delay setting will honor only one of: 二选一,按ip还是按域名设置请求上限
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
CONCURRENT_REQUESTS_PER_IP = 16 # Disable cookies (enabled by default) 自动处理cookie,需要登录会话
#COOKIES_ENABLED = False
COOKIES_ENABLED = True # Disable Telnet Console (enabled by default)
TELNETCONSOLE_ENABLED = False # Override the default request headers: 默认的http headers
DEFAULT_REQUEST_HEADERS = {
'Connection': 'Keep-Alive',
'Accept': 'text/html, application/xhtml+xml,*/*',
'Accept-Language': 'zh-CN',
'Accept-Encoding': 'gzip, deflate',
}

其实看注释就已经很清楚各个配置项是什么作用了,根据自己的需求,目标网站的反爬虫策略来配置就好了

另外可以任意添加自己自定义的配置项,比如MySQL配置:

# MYSQL CONFIG
MYSQL_HOST = '127.0.0.1'
MYSQL_PORT = 3307
MYSQL_USER = 'root'
MYSQL_PASS = ''
MYSQL_NAME = 'pets'

在项目中需要使用的时候,使用 crawler 对象。在 pipelines.py 中 的例子:

@classmethod
def from_crawler(cls, crawler):
'''static function'''
host = crawler.settings.get('MYSQL_HOST')
...

pipelines.py 管道处理

管道处理,根据字面意思当然是可以定义不同的逻辑,按顺序对 Items 进行处理。

管道顺序

管道的顺序需要在 settings.py 定义

 ITEM_PIPELINES = {
# enable image pipeline
'cats.pipelines.FilterPipeline': 1,
'cats.pipelines.ImgsPipeline': 100,
'cats.pipelines.CatsPipeline': 300,
}

这里定义了3个管道,分别是 过滤去重 -> 下载图片 -> 保存到数据库 。后面的数字代表管道权重

@classmethod[from_crawler] 初始化管道

这个是从官方文档看到的,为了从 settings.py 读取相关配置,调用类方法来初始化 管道处理器。在使用数据库的时候很方便:

db = None
cursor = None def __init__(self, conf):
try:
self.db = pymysql.connect(conf['host'], conf['user'], conf['pass'], conf['name'], port=conf['port'], charset='utf8')
except pymysql.OperationalError as e:
print ("Mysql Operation Error[%d]: %s" % tuple(e))
exit(0)
self.cursor = self.db.cursor() def __del__(self):
self.db.close() @classmethod
def from_crawler(cls, crawler):
'''static function'''
return cls({
'host' : crawler.settings.get('MYSQL_HOST'),
'port' : crawler.settings.get('MYSQL_PORT'),
'name' : crawler.settings.get('MYSQL_NAME'),
'user' : crawler.settings.get('MYSQL_USER'),
'pass' : crawler.settings.get('MYSQL_PASS')
})

process_item() 管道处理方法

这里是对 Item 进行处理的主要方法,数据库落地或者 DropItem() .处理完成记得 return item

sql = "SELECT id FROM cat_imgs WHERE img_hash=%s"
self.cursor.execute(sql, (item['img_hash'], ))
if self.cursor.fetchone():
spider.log('HASH exists.')
raise DropItem("HASH exists.")
else:
return item

ImagesPipeline 图片下载

【官方文档】Downloading and processing files and images

  • 新建一个类继承 ImagesPipeline。因为不是普通的 pipeline,因此__init__(),process_item(),spider_open(),from_crawler() 等方法可能不适用

  • get_media_requests(self, item, info) 下载图片方法第三个参数info存储了spider的信息,可以直接获取spider的属性:

      def get_media_request(self, item, info):
    name = info.spider.name
    ref = info.spider.ref
    return Request(item['img_src'], headers={"Referer": ref})
  • item_completed(self, results, item, info) 图片下载完成后的处理。results参数始终是一个 list, 跟你定义的 Item 字段没有关系

      def item_completed(self, results, item, info):
    
          for ok,x in results:
    if not ok:
    raise DropItem("Item contains no files")
    item['img_src'] = x['path']
    # 我的 item 结构中 只有一个图片资源
    return item

Image 图片下载配置

IMAGES_STORE = r'C:\Users\admin\PycharmProjects\cats\cats\imgs'
# image thumb size
IMAGES_THUMBS = {
# 缩略图最大宽高
'small': (90, 90),
}
# image filter size,宽高小于这个尺寸不下载
IMAGES_MIN_HEIGHT = 120
IMAGES_MIN_WIDTH = 120
# redirect download url,有些图片链接包含重定向
MEDIA_ALLOW_REDIRECTS = True

spiders 爬虫逻辑

爬虫执行的命令scrapy crawl xxx,这里的爬虫名字就是xxx_spider.py 里定义的 name 属性。 name 不需要要跟文件名一致

启动爬虫并传参

def __init__(self, page_range='1-10', *args, **kwargs):
super(xxxSpider, self).__init__(*args, **kwargs)
self.start, self.end = page_range.split('-')

启动命令大概是 scrapy crawl xxx -a page_range=1-5

传多个参数的方法暂时没有找到很好的解决方法,因此利用参数序列化成为一个参数的方式。不知道是不是因为window-cmd的关系。

yieldreturn

刚学python,因此对 yield 一开始没有概念。个人觉得在爬虫这个场景下,可以这么理解:

  • Return : 立即返回一个 request 请求(或返回一个 item)
  • Yield : 注册一个 request 请求(或一个 item),供后面的逻辑管道处理

    因此需要返回多个请求(item)的用yield,相当于一个请求列表;确定只有一个请求,可以用return(yield 应该也没问题)

Xpathcss

  • .extract() 获取一个目标列表,.extract_first() 获取列表第一个元素

  • 获取标签内容:.css('div::text'),.xpath('//div/text()')

  • 获取标签属性:.css('a::attr(href)'),.xpath('//a/@href')

  • xpath 比 css 要更快一些,css 选择器会被解释为 xpath 选择器

  • 注释内容无法通过 text() 获取,尝试通过获取整个元素再去掉 然后重新构造选择器,比如 抓取百度贴吧的时候它的源码是这样的:
      <html>....</html>
    <code id="..." class="..."><!--
    <ul class="...">
    <li>......</li>
    </ul>
    --></code>

    看起来像是用了某种前端框架,真实 html 内容被放在了 标签 并注释掉了。这时直接使用 xpath 是无法获取 code 里的 html 内容的

      thread_list = res.xpath('//html/code[@id="pagelet_html_frs-list/pagelet/thread_list"]').extract_first()
    # 去掉注释
    exp = re.compile(r'<code.*><!--(.*)--></code>', re.I|re.M|re.S)
    thread_list = re.sub(exp, r'\1', thread_list)
    # 重新加载内容
    topic = Selector(text=thread_list).xpath('//a[@class="j_th_tit "]')

其他

  • scrapy 为我们造好了绝大部分轮子,我们需要做的就是熟悉它。
  • 需要自己开发的功能,主要是研究如何从目标站点的html结构中获取自己需要的内容,以及对应的存储逻辑
  • 其他一些开发,可能是遇到特殊的反爬虫策略,也可能是对 scrapy 的部分功能还不够熟悉

Scrapy 框架进阶笔记的更多相关文章

  1. Scrapy框架学习笔记

    1.Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网 ...

  2. Scrapy 框架 (学习笔记-1)

    环境: 1.windows 10 2.Python 3.7 3.Scrapy 1.7.3 4.mysql 5.5.53 一.Scrapy 安装 1. Scrapy:是一套基于Twisted的一部处理框 ...

  3. scrapy框架使用笔记

    目前网上有很多关于scrapy的文章,这里我主要介绍一下我在开发中遇到问题及一些技巧: 1,以登录状态去爬取(带cookie) -安装内容: brew install phantomjs (MAC上) ...

  4. scrapy爬虫框架学习笔记(一)

    scrapy爬虫框架学习笔记(一) 1.安装scrapy pip install scrapy 2.新建工程: (1)打开命令行模式 (2)进入要新建工程的目录 (3)运行命令: scrapy sta ...

  5. Python爬虫进阶三之Scrapy框架安装配置

    初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此整理如下. Windows 平台: 我的系统是 ...

  6. Python爬虫进阶之Scrapy框架安装配置

    Python爬虫进阶之Scrapy框架安装配置 初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此 ...

  7. Python爬虫进阶(Scrapy框架爬虫)

    准备工作:           配置环境问题什么的我昨天已经写了,那么今天直接安装三个库                        首先第一步:                           ...

  8. PYTHON 爬虫笔记十一:Scrapy框架的基本使用

    Scrapy框架详解及其基本使用 scrapy框架原理 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...

  9. 爬虫写法进阶:普通函数--->函数类--->Scrapy框架

    本文转载自以下网站: 从 Class 类到 Scrapy https://www.makcyun.top/web_scraping_withpython12.html 普通函数爬虫: https:// ...

随机推荐

  1. MySQL中处理Null时要注意两大陷阱

    MySQL数据库是一个基于结构化数据的开源数据库.SQL语句是MySQL数据库中核心语言.不过在MySQL数据库中执行SQL语句,需要小心两个陷阱. 陷阱一:空值不一定为空 空值是一个比较特殊的字段. ...

  2. Linux课程---8、Linux启动流程

    Linux课程---8.Linux启动流程 一.总结 一句话总结: grub启动引导界面(比如装了多系统,选择系统),找到linux内核 启动init程序,加载各种驱动 1.进入grub界面选择相应的 ...

  3. 英语发音规则---/ŋ/与/ŋg/的读音区别

    英语发音规则---/ŋ/与/ŋg/的读音区别 一.总结 一句话总结: 1.位于词中间的字母组合ng,有时读作/ ŋ /,有时读作/ ŋg/? singer ['sɪŋə] n. 歌手 ringing ...

  4. php: 0跟字符串做比较永远是true。 php大bug。

    php: 0跟字符串做比较永远是true. php大bug. 如: $a = 0; if( $a == 'excel') { echo "yes"; }else{ echo &qu ...

  5. Android之史上最全最简单最有用的第三方开源库收集整理

    Android开源库 自己一直很喜欢Android开发,就如博客签名一样, 我是程序猿,我为自己代言 . 在摸索过程中,GitHub上搜集了很多很棒的Android第三方库,推荐给在苦苦寻找的开发者, ...

  6. 使用kill命令终止进程shell脚本

    因有的程序使用kill才能结束掉进程,没有关闭脚本,以我司的服务为例,服务名叫asset-server服务,只有启动脚本,自编写关闭脚本,及重启动脚本. 关闭服务脚本. vim asset-shutd ...

  7. Python 爬虫 —— 文件及文件夹操作

    0. 文件名.路径信息.拓展名等 #取文件后缀 >>> os.path.splitext("/root/a.py") ('/root/a', '.py') #取目 ...

  8. 【遍历二叉树】01二叉树的前序遍历【Binary Tree Preorder Traversal】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的前序遍历的 ...

  9. bzoj1067降雨量

    True和False都好搞 Maybe的情况: 1.Y年和X年的降雨量已知,X年的降雨量不超过Y年的降雨量,从Y+1到X-1年中存在至少一年的降雨量未知,从Y+1到X-1年中已知的降雨量都小于X年的降 ...

  10. Qt Quick之TableView的使用

    本博只是简单的展示TableView的基本使用(TableView.style:TableViewStyle.headerDelegate.rowDelegate.itemDelegate.Table ...