前言
scrapy是一个强大的爬虫框架,熟练地使用它几乎可以随心所欲地抓取任何网页上想要获得的数据。笔者初学爬虫,需要项目练手,适逢有不少朋友热衷于《原神》这款由米哈游开发的游戏,出于对角色数据的好奇,便选择了米哈游的官网数据作为了实战目标。
项目建立
scrapy项目的建立很简单,只需要打开cmd,cd到你要建立项目的目录下,输入一行指令:
scrapy startproject 项目名称
随后打开目录,你可以发现建立了一个文件夹(笔者这里的项目名称即juese)打开以后,有一个同名文件夹和一个scrapy.cfg。我们的第一步到这里就完成了!
爬虫代码编写
项目建立完了以后,就开始编写爬虫了。首先,第二个juese文件夹里有一个spiders文件夹,在这个文件夹中建立一个.py文件,我的文件就叫做spider.py
然后开始编写,首先要编写的是上一个目录的items.py文件,这个文件里面的内容代表了你要爬的数据名称,大致如下:
import scrapy
class JueseItem(scrapy.Item):
name = scrapy.Field()
hp_1 = scrapy.Field()
attack_1 = scrapy.Field()
defend_1 = scrapy.Field()
然后就可以开始编写刚刚建立的spider.py文件了,直接贴代码:
import scrapy
import sys
sys.path.append('D:/juese/juese')
from items import JueseItem
class JueseSpider(scrapy.Spider):
name = 'juese'
allowed_domains = ["mihoyo.com"]
start_urls = ['https://bbs.mihoyo.com/ys/obc/content/90/detail?bbs_presentation_style=no_header&tdsourcetag=s_pctim_aiomsg']
其中,导入sys库是为了能调用上级目录的items.py
我们新建了一个爬虫类,前三个变量非常关键,代表了爬虫名字,爬虫的限定区域和起始的网页,变量名不能更改。起始的网页即米哈游的官网里原神的角色索引。那么,由这些角色索引怎样获得各个角色的信息呢?所以第一步就是要去爬下一级页面的连接,这里的方法名parse不能更改。
def parse(self,response):
item = JueseItem()
hrefs = response.xpath("//*[@id='__layout']/div/div[2]/div[2]/div/div[1]/div[2]/div[2]/div/div/div[3]/div/table/tbody/tr/td/a/@href").extract()
for href in hrefs:
href = "https://bbs.mihoyo.com/" + href
yield scrapy.Request(href, callback=self.new_parse, meta={'item':item})
接上一块代码,这里用到了Xpath解析。笔者这里的Xpath解析过于冗长,但实际上是比较适合初学者的写法。获取Xpath有一种非常快捷的方法:
按F12打开网页架构,找到需要抓取的内容,直接复制它的Xpath解析,粘贴到你的代码里即可。
然后是非常重要的一个内容!就是scrapy的Request方法,这个方法的用法就如代码所示,它相当于点进了你爬到的那些二级页面,这里创建了一个新方法new_parse用于我们在二级页面的爬虫,并且需要继承之前用到的item.完成了这一步,就可以正式进行内容的爬取了。
def new_parse(self,response):
item = response.meta['item']
item['name'] = response.xpath("//*[@id='__layout']/div/div[2]/div[2]/div/div[1]/div[2]/h1/text()")[0].extract()
item['hp_1'] = response.xpath("//*[@id='__layout']/div/div[2]/div[2]/div/div[1]/div[2]/div[2]/div[1]/div[5]/table/tbody/tr[2]/td[2]/div/span/text()")[0].extract()
item['attack_1'] = response.xpath("//*[@id='__layout']/div/div[2]/div[2]/div/div[1]/div[2]/div[2]/div[1]/div[5]/table/tbody/tr[3]/td[2]/div/span/text()")[0].extract()
item['defend_1'] = response.xpath("//*[@id='__layout']/div/div[2]/div[2]/div/div[1]/div[2]/div[2]/div[1]/div[5]/table/tbody/tr[4]/td[2]/div/span/text()")[0].extract()
yield item
Xpath解析的获取和之前一样,对于文本内容需要注意的是最后必须有text(),以及用这种方法获得的数据实际是列表格式的,所以需要加一个[0]来去掉列表。至此,spider.py文件就编写完成。
爬虫运行
可以用cmd运行,这里介绍一种用pycharm来代替cmd的方法:
from scrapy import cmdline
cmdline.execute("scrapy crawl juese".split())
在spider.py的同级目录下建立一个名为begin.py的文件添加上述代码并运行,这相当于你打开cmd,在当前目录下执行scrapy crawl juese的指令。但用pycharm来代替方便了不少。
可以看到,数据获取完整,爬虫执行成功。
导出到Excel
将数据导出到Excel往往是必不可少的工作,方法有很多,笔者采用的是一种较为直观简单的方法。不过不管是什么方法,有一步是必须做的,那就是打开第一个juese文件中的settings.py,将ROBOTSTXT_OBEY = True的True改成False,并添加一段代码(也可以通过删去一些注释符实现):
ITEM_PIPELINES = {
'juese.pipelines.JuesePipeline': 300,
}
保存退出,然后打开pipelines.py文件,开始编写导出的代码:
class JuesePipeline(object):
def __init__(self):
result = open('juese.xls', 'w', encoding='gbk')
result.write('角色\t等级\t生命值\t攻击力\t防御力\t额外属性\n')
def process_item(self, item, spider):
result = open('juese.xls','a',encoding='gbk')
l = []
l.append([item['name'],1,item['hp_1'],item['attack_1'],item['defend_1'],0])
l.append([item['name'],20,item['hp_20'],item['attack_20'],item['defend_20'],0])
l.append([item['name'],40,item['hp_40'],item['attack_40'],item['defend_40'],item['bonus_40']])
l.append([item['name'], 50, item['hp_50'], item['attack_50'], item['defend_50'], item['bonus_50']])
l.append([item['name'], 60, item['hp_60'], item['attack_60'], item['defend_60'], item['bonus_50']])
l.append([item['name'], 70, item['hp_70'], item['attack_70'], item['defend_70'], item['bonus_70']])
l.append([item['name'], 80, item['hp_80'], item['attack_80'], item['defend_80'], item['bonus_80']])
l.append([item['name'], 90, item['hp_90'], item['attack_90'], item['defend_90'], item['bonus_90']])
for i in range(8):
for j in range(6):
result.write(str(l[i][j]))
result.write('\t')
result.write('\n')
return item
由于笔者实际爬取的是1-90级的某角色属性,所以同一个角色也需要大量分行。至于写入Excel文件,就是for循环然后一格一格地写,写满一行换行,应该算是比较朴实的办法了。
可以看到角色们一个不落地被我们扒到了Excel里,至此我们的爬虫项目就全部完成了!
后记
这是笔者的第一个scrapy爬虫项目和第一篇csdn,很多用语不够专业,实在是学的不够精所致。不过,读到大二以来,这也算是不小的进步了,希望能帮一些同样的爬虫初学者们少走一点弯路。如有谬误恳请指出,感激不尽!!