由于b站爬虫难度较小(url地址主要通过av定位),我第一的爬虫尝试就选择了b站

以下为初步的尝试。

首先,由于初步统计,b站空视频(已下架或者删除)的比例大概是百分之五十(统计样本基本在前几年的视频中),因此,我觉得使用简单的迭代搜索问题不大(如果为了减少一半的搜索量写大量爬虫逻辑代码比较浪费时间)我使用的是python自带的request获取b站页面源代码,然后本来想直接获取数据。然而,开始的数据(硬币,播放数等)并不能很容易的获取。因为b站的数据都是通过js动态加载,直接用request只能获得静态页面。不过问题不大,通过使用chrome开发者工具的监听抓包,我找出了js文件并发现b站对外的公共接口

弹幕接口为:http://comment.bilibili.com/%s.xml %cid

视频信息接口为:https://api.bilibili.com/x/web-interface/archive/stat?aid=%s %aid

其中,aid和cid为两个可以从页面源代码中获取的编号

以上,基本完成对b站视频的爬虫,当然单线程会出现速度慢的问题,目前先用

from multiprocessing.pool import Pool

解决,处理速度大概是100条/s,其中70%的时间用于request获取页面源码,30%时间用于request获取视频信息接口的json包

之后,看了网上的爬虫教程,部分人推荐使用seleium+PhantomJS的框架,因为PhantomJS作为无头浏览器,可以直接获取动态页面的数据,就可以不用再用抓包和访问api的方式获取信息了。但是,尽管PhantomJS是无头浏览器,相对的对系统的负载较小,但相对于传统的爬虫,功能上的损耗还是比较大的,经过测试,似乎除去了获取json包的时间,使用seleium的获取速度甚至比不上之前使用多线程的requests。这方面的问题可能需要再思考一下。

经统计,目前b站视频总数大概是2000,0000个,而且还在持续增长中,如果用100/s的速度获取,需要20,0000s,折合55h。这个数据应该还有改进的空间。

目前想到的是两种改进方式:

1.优化爬虫逻辑,筛除已下架视频(大概可以减少一半的时间)

2.尝试使用scrapy框架

另:目前用万级数据测试似乎没有因为访问频率过快被禁止访问,如果出现该情况应该会用sleep和尝试使用多ip地址访问

useRequest:

# -*-  coding:utf-8 -*-
import requests
import re
import json
import copy
from savecsv import savecsv
from savecsv import csvhead
from multiprocessing.pool import Pool
import time # driver = webdriver.PhantomJS()
# driver.get("https://www.bilibili.com")
# count = 0
# dict = {}
# # @profile
def myspider(av):
dict = {}
# global count
# global dict
url = 'https://www.bilibili.com/video/av%s/' % str(av)
resp = requests.get(url)
page = resp.text
temp = re.search(r'<div class="v-title"><h1 title="(.+?)">', page)
if temp:
# count += 1
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
if aid:
page = requests.get('https://api.bilibili.com/x/web-interface/archive/stat?aid=%s' % aid).text
info = json.loads(page)
dict[av] = copy.deepcopy(info['data'])
dict[av]['title'] = title.encode('utf-8')
dict[av]['author'] = author.encode('utf-8')
savecsv(dict, "test.csv")
# print title
# print aid
# print cid if __name__ == "__main__":
start = time.time()
csvhead(['av','硬币','排名','copyright','标题','分享','up主','收藏','弹幕数','回复','aid','','最高排名','观看数'], 'test.csv')
results = []
mypool = Pool(processes=100)
for av in xrange(10000):
results.append(mypool.apply_async(myspider, args=(av,)))
# myspider(7)
mypool.close()
mypool.join()
end = time.time()
print str(end - start)+'s'
useSeleium:
# -*-  coding:utf-8 -*-
import requests
import re
import json
import copy
from savecsv import savecsv
from savecsv import csvhead
from multiprocessing.pool import Pool
import time
from selenium import webdriver # driver = webdriver.PhantomJS()
# driver.get("https://www.bilibili.com")
# count = 0
# dict = {}
# # @profile
def myspider(av):
dict = {}
# global count
# global dict
url = 'https://www.bilibili.com/video/av%s/' % str(av)
service_args = []
service_args.append('--load-images=no') ##关闭图片加载
service_args.append('--disk-cache=yes') ##开启缓存
service_args.append('--ignore-ssl-errors=true') ##忽略https错误
service_args.append('--ssl-protocol=any')
driver = webdriver.PhantomJS(service_args=service_args)
driver.get(url)
page = driver.page_source
# resp = requests.get(url)
temp = re.search(r'<div class="v-title"><h1 title="(.+?)">', page) if temp:
# count += 1
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)
driver.quit()
print aid
print cid
print title if __name__ == "__main__":
start = time.time()
csvhead(['av','硬币','排名','copyright','标题','分享','up主','收藏','弹幕数','回复','aid','','最高排名','观看数'], 'test.csv')
results = []
# mypool = Pool(processes=100)
# spiderpath()
for av in xrange(10):
# results.append(mypool.apply_async(myspider, args=(av,)))
myspider(av)
# mypool.close()
# mypool.join()
end = time.time()
print str(end - start)+'s'

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

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

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

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

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

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

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

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

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

  5. 基于Scrapy的B站爬虫

    基于Scrapy的B站爬虫 最近又被叫去做爬虫了,不得不拾起两年前搞的东西. 说起来那时也是突发奇想,想到做一个B站的爬虫,然后用的都是最基本的Python的各种库. 不过确实,实现起来还是有点麻烦的 ...

  6. 爬虫第六篇:scrapy框架爬取某书网整站爬虫爬取

    新建项目 # 新建项目$ scrapy startproject jianshu# 进入到文件夹 $ cd jainshu# 新建spider文件 $ scrapy genspider -t craw ...

  7. 【Python爬虫案例】用Python爬取李子柒B站视频数据

    一.视频数据结果 今天是2021.12.7号,前几天用python爬取了李子柒的油管评论并做了数据分析,可移步至: https://www.cnblogs.com/mashukui/p/1622025 ...

  8. 某图片站反爬加密字段x-api-key破解

    前言 此次逆向的是某“你们都懂”领域的图片站,目前此站限制注册,非会员无法访问:前两天偶然搞到了份邀请码,进入后发现质量还可以,于是尝试爬取,在爬虫编写过程中发现此站点采用了不少手段来阻止自动化脚本( ...

  9. Scrapy (网络爬虫框架)入门

    一.Scrapy 简介: Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,Scrapy 使用了 Twisted['twɪstɪd](其主要对手是Tornado) ...

随机推荐

  1. Spring mybatis源码篇章-Mybatis的XML文件加载

    通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-Mybatis主文件加载 前话 前文主要讲解了Mybatis的主文件加载方式,本文则分析不使用主文件加载方式 ...

  2. loadrunner如何监控linux,以及重点指标分析

    监控UNIX一. lr监控UNIX ,UNIX先启动一rstatd服务 以下是在IBM AIX系统中启动rstatd服务的方法: 1. 使用telnet以root用户的身份登录入AIX系统 2. 在命 ...

  3. 在springMVC框架中集成quartz作业调度器

    1.首先需要导入这几个jar包,如下图: 其中log4j,quartz,slf4j-api,slf4j-log4j12我是在项目中都引用了 2.引用完jar包后,新建一个作业调度类,执行作业调度逻辑, ...

  4. Linux (x86) Exploit 开发系列教程之四(使用return-to-libc绕过NX bit)

    (1)原理: “NX Bit”的漏洞缓解:使某些内存区域不可执行,并使可执行区域不可写.示例:使数据,堆栈和堆段不可执行,而代码段不可写. 在NX bit打开的情况下,基于堆栈的缓冲区溢出的经典方法将 ...

  5. T100——程序从标准签出客制后注意r.c和r.l

    标准签出客制后,建议到对应4gl目录,客制目录 r.c afap280_01 r.l afap280_01 ALL 常用Shell操作命令: r.c:编译程序,需在4gl路径之下执行,产生的42m会自 ...

  6. 怎样使用js将文本复制到系统粘贴板中

    需要使用到三个document方法: 1. document.execCommand(); 执行某个命令 2. document.queryCommandSupported(); 检测浏览器是否支持某 ...

  7. django websocket 实现后台日志在web端展示(+前端vue设置)

    核心代码: @accept_websocket def get_log(req): if req.is_websocket(): print('收到websocket请求') with open(se ...

  8. 电脑串口(com)被占用问题

    最近使用串口与设备通信. 这个电脑一个有6个COM口,都要使用. 还有自带一个华为的4G通信模块,这个模块需要虚拟出4个COM口. 使用之前的Gost系统(只有1个物理COM版本的),导致物理COM口 ...

  9. WinSockAPI多线程服务器

    运行效果: 程序: // TcpServer.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream&g ...

  10. Eclipse MyEclipse 反编译.class文件 myeclipse source not found

    首先,需要下载两个必须的插件包. 一个是:准备反编译需要的jad.exe 下载地址:http://varaneckas.com/jad/ 二个是:反编译编辑器net.sf.jadclipse_3.3. ...