1. 安装Scrapy
1) 如果安装了 anaconda,直接使用 conda install scrapy
2) 没有anacoda,如果使用install scrapy 安装报错,可以https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted 下载Twisted,
我这里是python是3.7 版本的,所以下载cp37这个。
下载完后,在命令行 输入 pip install Twisted的路径名+Twisted文件名
2. 创建scrapy 项目
在命令行输入: scrapy startproject 项目名
进到项目路径里面,
命令行 执行
scrapy genspider BiliRank www.bilibili.com
BiliRank 就是 spiders下生成的自定义的spider, www.bilibili.com 就是规定了这个爬虫只会爬取这个域名下的连接。
创建好后,用pyrcharm打开,可以看到项目的结构,这个run.py 是后加的 这个放到下面再说。
1) spiders 文件夹,是一个自定义爬虫,这里面可以实现自己需要实现的爬虫功能。
2)items,这里面声明了数据字段
3)middlewares.py, 这里定义了一些中间件
4)pipelines.py,这里定于了数据输出方式,比如写到数据库去
5) settings.py 这里给出了常用的一些配置项
是否遵守robots协议
组装user-agent
配置并发度
每次请求的请求延迟
配置请求头
设置管道优先级
给出了一些常用的配置,其他配置可以根据情况再进行修改。
3. 爬取b站排行榜
1) items中声明字段名
class BilivideorankItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
playVolume = scrapy.Field()
barrage = scrapy.Field()
overallRatings = scrapy.Field()
author = scrapy.Field()
rank = scrapy.Field()
2)编辑spider方法,爬取需要的字段
class BilirankSpider(scrapy.Spider):
name = 'biliVideoRank'
allowed_domains = ['www.bilibili.com']
# 这里放了一个需要爬取的url数组,需要爬取的url 可以从页面获取。
start_urls = ['https://www.bilibili.com/v/popular/rank/all']
# 使用xpath解析,也可以使用bs等其他的方式
urls = ["https://www.bilibili.com/v/popular/rank/douga", "https://www.bilibili.com/v/popular/rank/guochuang"]
def parse(self, response):
html = etree.HTML(response.text)
title = html.xpath(
'//div[@class="rank-container"]/div[@class="rank-list-wrap"]/ul/li//div[@class="info"]/a/text()')
playVolume = html.xpath(
'//div[@class="rank-container"]/div[@class="rank-list-wrap"]/ul/li//div[@class="info"]//div[@class="detail"]/span[1]/text()')
barrage = html.xpath(
'//div[@class="rank-container"]/div[@class="rank-list-wrap"]/ul/li//div[@class="info"]//div[@class="detail"]/span[2]/text()')
overallRatings = html.xpath(
'//div[@class="rank-container"]/div[@class="rank-list-wrap"]/ul/li//div[@class="info"]//div[@class="pts"]/div/text()')
author = html.xpath(
'//div[@class="rank-container"]/div[@class="rank-list-wrap"]/ul/li//div[@class="info"]//span[@class="data-box up-name"]/text()')
rank = html.xpath(
'//div[@class="rank-container"]/div[@class="rank-list-wrap"]/ul/li[@class="rank-item"]/div[@class="num"]/text()')
for t, p, b, o, a, r in zip(title, playVolume, barrage, overallRatings, author, rank):
item = BilivideorankItem()
item['title'] = str(t).strip()
item['playVolume'] = str(p).strip()
item['barrage'] = str(b).strip()
item['overallRatings'] = str(o).strip()
item['author'] = str(a).strip()
item['rank'] = str(r).strip()
# 需要连续爬取多个url的时候,这里要使用yield 不能使用return
yield item
if len(self.urls)>0:
url = self.urls.pop(0)
# 这里回调parse这个函数
yield scrapy.Request(url=url, callback=self.parse)
else:
return
3) 自定义piplines
class BilivideorankPipeline:
def process_item(self, items, spider):
return items
class BilivideorankMysqlPipeline:
def __init__(self):
self.connect = pymysql.connect(
host="localhost",
port=3306,
db="test",
user="root",
passwd="12301230",
charset='utf8',
use_unicode=True)
self.cursor = self.connect.cursor()
def process_item(self, item, spider):
# 数据入库
sql = "insert into t_bili_rank(b_title,b_play_volume,b_barrage,b_overall_ratings,b_author,b_rank) values ('%s','%s','%s','%s','%s','%s')" % \
(item['title'], item['playVolume'], item['barrage'], item['overallRatings'], item['author'], item['rank'])
self.cursor.execute(sql)
self.connect.commit()
# 这里的return不能省略
return item
4)编写run.py
为了简便运行,不必每次都在命令行运行,可以创建一个这样的文件,作为程序运行的入口,启动程序。
from scrapy import cmdline
cmdline.execute('scrapy crawl biliVideoRank'.split())