前几天学习了scrapy的框架结构和基本的使用方法,部分内容转载自:http://blog.csdn.net/qq_30242609/article/details/52810840

scrapy由编写蜘蛛的spiders文件夹和其他框架自带的几个python文件组成

其中

items.py

双击打开这个文件,看一下都初始化了什么东西

# -*- coding: urf-8 -*-
# Define here the models for your scrapyed items
#
# See documentation in
# http://doc.scrapy.org/en/latest/topics/items.html import scrapy class HeartsongItem(scrapy.Item):
# define the fields for your item here like:
#
# name = scrapy.Filed()
pass
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

通过里面的注释可见,这个文件的作用是定义我们要爬取信息的标准格式,打个比方说,如果我们要爬取一批人的个人信息,包括姓名,性别,生日,那么我们可以这样来书写这个文件

import scrapy

class HeartsongItem(scrapy.Item):
name = scrapy.Filed()
sex = scrapy.Filed()
birthday = scrapy.Filed()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

易见本文件只是定义了一个类,至于什么时候实例化它,怎么保存它,请继续了解下面的内容。

settings.py

如其名,这是本项目的配置文件,里面注释着很多常用的配置项,我们通过在其他文件中引入本文件的方式来使用这些配置项。 
当然,我们可以把这些注释都删掉,等需要开启哪个功能的时候再另行编辑。 
我们此处先看看默认打开的配置项吧

BOT_NAME = 'heartsong'
SPIDER_MODULES = ['heartsong.spiders']
NEWSPIDER_MODULE = 'heartsong.spider'
# Obey robots.txt rules
ROBORSTXT_OBEY = True
  • 1
  • 2
  • 3
  • 4
  • 5

因为我们写的是定向爬虫,前面三个按默认即可,我们不去管他。看第四项,注释里说这个配置项的意思是是否遵守robots.txt,那么robots.txt是个什么东西呢? 
通俗来说,robots.txt是遵循Robot协议的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在Scrapy启动后,会在第一时间访问网站的robots.txt文件,然后决定该网站的爬取范围。 
当然,我们并不是在做搜索引擎,而且在某些情况下我们想要获取的内容恰恰是被robots.txt所禁止访问的。所以,我们就将此配置项设置为False,拒绝遵守Robot协议

pipelines.py

双击打开这个文件,看看都初始化了什么东西

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html class HeartsongPipeline(object):
def process_item(self, item, spider):
return item
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

从注释中所能得到的信息微乎其微,只告诉我们要启用此文件的话必须要在settings.py里配置一下ITEM_PIPELINES,好,那我们就老老实实的去settings.py里配置一下吧,不过注意,此处有坑,在1.0.x版本(极客学院教程中使用),配置项用list格式来书写,而在最新的1.1.2版本中,需要用dict格式,否则会报错,无法爬取,配置好后,我们的setting.py如下:

# -*- coding: utf-8 -*-

BOT_NAME = 'heartsong'
SPIDER_MODULES = ['heartsong.spiders']
NEWSPIDER_MODULE = 'heartsong.spider' ROBORSTXT_OBEY = True ITEM_PIPELINES = {
'heartsong.pipelines.HeartsongPipeline': 300,
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

此处的300表示优先级,因为本项目只用到这一个pipeline,所以随意取0-1000中的一个数值即可。 
好,镜头切回pipelines.py,这个文件到底有什么用呢?当然用处很多啦,本教程中介绍的作用只有两个: 
* 对爬取到的数据(Item)进行处理,比如存入数据库 
* 爬虫结束时产生事件,比如发送一封邮件

爬虫

在默认生成的spiders目录下新建heartsong_spider.py,我们的爬虫就写在这里面,因为是介绍,那么此处就写个简单的下载网站的主页,让大家能运行一下,感受一下scrapy。

import scrapy

class HeartsongSpider(scrapy.spiders.Spider):
name = "heartsong" # 爬虫的名字,执行时使用
allowed_domains = ["heartsong.top"] # 允许爬取的域名,非此域名的网页不会爬取
start_urls = [
"http://www.heartsong.top" # 起始url,此例只爬这一个页面
] def parse(self, response): # 真正的爬虫方法
html = response.body # response是获取到的来自网站的返回
# 以下四行将html存入文件
filename = "index.html"
file = open(filename, "w")
file.write(html)
file.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

要说明的是,这个类不是随心所欲来写的,name,allowed_domains,start_urls,都是类似于”重载”的值。也就是说,scrapy内部会检测这些变量的值,变量名不可以起成其它的名字,类似的变量之后还会有介绍。至于parse方法,就是重载的父类的方法,我们爬虫的主体一般就写在这里面。 
好,现在让我们来运行它 
在命令行中进入heartsong目录下,执行命令

scrapy crawl heartsong
  • 1

此处的名字heartsong是与爬虫类中的name保持一致。   

以上是scrapy的基本架构。

由于递归爬取的时候存在超链接指向图片等问题反而增加request工作量,目前主要思考通过首先爬取所有up主信息,再爬取其空间内视频信息的办法。但是具体的爬取方案无法确定。如果要采取不遗漏的方法,又只能从视频方面开始爬取,回到了最初的问题。目前error视频的数量大概占总数量的一半,问题还不是很大,暂时搁置递归爬取的问题。

目前依然采取根据av号枚举的方式访问视频并记录信息。根据测试程序的反馈,scrapy的爬取效率并不比request的方法高多少。。。可能有部分人认为的效率高主要由于scrapy自带的多进程爬取的方法。但是当request也采取多进程爬取时,主要耗时依然在于获取网络源码的过程中。这部分的时间目前没有办法减少。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import scrapy
import re class bilibili(scrapy.Spider):
name = "bilibili"
# 允许的域名
allowed_domains = ["bilibili.com"]
start_urls = []
for av in xrange(10000):
start_urls.append("http://www.bilibili.com/video/av"+str(av)) def parse(self, response):
page = response.body
temp = re.search(r'<div class="v-title"><h1 title="(.+?)">', page)
if temp:
title = re.search(r'<div class="v-title"><h1 title="(.+?)">', page).group(1)
authorkit = re.search(r'r-info.+?title="(.+?)"', page)
if authorkit:
author = authorkit.group(1)
aid = re.search(r'aid=(\d+)', page).group(1)
cid = re.search(r'cid=(\d+)', page).group(1)
print cid
print aid
url = 'https://api.bilibili.com/x/web-interface/archive/stat?aid='+str(aid)
return scrapy.http.Request(url=url, callback=self.parse_item_page) def parse_item_page(self, response):
print response.body

关于b站爬虫的尝试(二)的更多相关文章

  1. 关于b站爬虫的尝试(一)

    由于b站爬虫难度较小(url地址主要通过av定位),我第一的爬虫尝试就选择了b站 以下为初步的尝试. 首先,由于初步统计,b站空视频(已下架或者删除)的比例大概是百分之五十(统计样本基本在前几年的视频 ...

  2. Python爬虫学习:二、爬虫的初步尝试

    我使用的编辑器是IDLE,版本为Python2.7.11,Windows平台. 本文是博主原创随笔,转载时请注明出处Maple2cat|Python爬虫学习:二.爬虫的初步尝试 1.尝试抓取指定网页 ...

  3. 【初码干货】记一次分布式B站爬虫任务系统的完整设计和实施

    [初码文章推荐] 程序员的自我修养 Azure系列文章 阿里云系列文章 爬虫系列文章 [初码产品推荐] AlphaMS开发模式 闪送达城市中央厨房 今天带来一个有意思的东西-分布式B站爬虫任务系统 这 ...

  4. 用Python+Aria2写一个自动选择最优下载方式的E站爬虫

    前言 E站爬虫在网上已经有很多了,但多数都只能以图片为单位下载,且偶尔会遇到图片加载失败的情况:熟悉E站的朋友们应该知道,E站许多资源都是有提供BT种子的,而且通常打包的是比默认看图模式更高清的文件: ...

  5. R语言爬虫初尝试-基于RVEST包学习

    注意:这文章是2月份写的,拉勾网早改版了,代码已经失效了,大家意思意思就好,主要看代码的使用方法吧.. 最近一直在用且有维护的另一个爬虫是KINDLE 特价书爬虫,blog地址见此: http://w ...

  6. 爬虫系列(十二) selenium的基本使用

    一.selenium 简介 随着网络技术的发展,目前大部分网站都采用动态加载技术,常见的有 JavaScript 动态渲染和 Ajax 动态加载 对于爬取这些网站,一般有两种思路: 分析 Ajax 请 ...

  7. Python爬虫初学(二)—— 爬百度贴吧

    Python爬虫初学(二)-- 爬百度贴吧 昨天初步接触了爬虫,实现了爬取网络段子并逐条阅读等功能,详见Python爬虫初学(一). 今天准备对百度贴吧下手了,嘿嘿.依然是跟着这个博客学习的,这次仿照 ...

  8. scrapy爬虫学习系列二:scrapy简单爬虫样例学习

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

  9. 爬虫简单之二---使用进程爬取起点中文网的六万多也页小说的名字,作者,等一些基本信息,并存入csv中

    爬虫简单之二---使用进程爬取起点中文网的六万多也页小说的名字,作者,等一些基本信息,并存入csv中 准备使用的环境和库Python3.6 + requests + bs4 + csv + multi ...

随机推荐

  1. oracle中row_number()的用法

    公司系统升级的时候需要数据迁移,遇到一个问题:新表的数据结构和旧表异构,旧表是流水号,新表是联合主键(业务号码+业务号码序号) 最后发现用窗口函数 row_number() + partition b ...

  2. 《Mysql 锁 - 概述》

    一:锁类型(加锁范围区分类型) - MySQL里面的锁可以分为:全局锁.表级锁.行级锁. 二:全局锁 - 作用 -  对整个数据库实例加锁. - 加锁方式 - MySQL提供加全局读锁的方法:Flus ...

  3. java源码 -- AbstractMap

    AbstractMap抽象类实现了一些简单且通用的方法,本身并不难.但在这个抽象类中有两个方法非常值得关注,keySet和values方法源码的实现可以值的学习. 抽象类通常作为一种骨架实现,为各自子 ...

  4. 前端开发 — HTML

    HTML HTML 超文本标记语言 HTML特征: 对换行和空格不敏感 空白折叠 1.1 HTML标签 标签也称为标记. 标签的种类: 1.双闭合标签 2.单闭合标签 1.1.1 head标签 met ...

  5. spring 框架的核心总结

    最近在学习Java语言,从而也学习了SpringFramework 这个大名鼎鼎的框架.从而做一些的记录. 题外话: 学习过几种不同的语言,后来知道所有的编程语言里所有的概念翻来覆去都是一样的事物,只 ...

  6. linux中部署jenkins(war包)及jenkins忘记登录账号密码

    未登录状态 登录状态 一:部署jenkins(war包) 1.直接下载war包jenkins.war,下载地址https://jenkins.io/download 2.将下载的war包放到服务器上t ...

  7. Codeforces 1249 D2. Too Many Segments (hard version)

    传送门 贪心 对于第一个不合法的位置,我们显然要通过删除几个覆盖了它的区间来使这个位置合法 显然删右端点更靠右的区间是更优的,所以就考虑优先删右端点靠右的,然后再考虑下一个不合法位置 用一个 $set ...

  8. MySQL 5.7 多源复制实践

    多源复制使用场景 数据分析部门会需要各个业务部门的部分数据做数据分析,这个时候就可以用到多源复制把各个主数据库的数据复制到统一的数据库中. 在从服务器进行数据汇总,如果我们的主服务器进行了分库分表的操 ...

  9. nodejs连接mysql数据库,报错Client does not support authentication protocol requested by server的解决方法

    最近想要尝试nodejs连接本地数据库,往全栈方向做一个小小的尝试,于是下载了一个 MySQL8.0,发现Navicat连接不上,结果就下载了mysql自身的Workbench,继续使用. 然而,难受 ...

  10. 同步/异步/阻塞/非阻塞/BIO/NIO/AIO

    转摘自:https://www.cnblogs.com/lixinjie/p/a-post-about-io-clearly.html 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HT ...