一、工作背景
组内的知识图谱项目需要有专业领域的实体名词和关系来构建,而心理学词库我已经从搜狗官网下载到了,使用词库这一想法来自于知乎一篇文章《只要5分钟!各专业词库任你挑》。词库下载后需要将.scel文件格式转换为.txt,附上Github。
而这篇文章的任务就是根据这些心理学领域词汇来获取百度百科的非结构化数据。我学习过程的大框架遵循简书的一个大牛史蒂文周,他的scrapy用法的系列文章,讲的很好。但工程实践方面参考的是具体的项目《农业领域知识图谱构建》,这个Github的代码讲解十分详尽。
二、scrapy使用记录
需要注意,如果要使用Pycharm,需要在工程目录执行命令,否则在pycharm界面不能显示这个项目。
step1、创建工程
scrapy startproject [工程名]
step2、查看工程
scrapy list #查看爬虫列表发现为空
scrapy genspider -l # 查看当前可以使用的爬虫模板
step3、生成爬虫文件
# 使用basic模板
scrapy genspider -t basic baiduSpider baidu.com
- 注意:需要在此工程目录下执行的命令
- 命令解释:basic是模板,baiduSpider是爬虫名,最后是域名
- 命令内部原理:
工程目录的spider目录下创建了一个baiduSpider.py的文件,里边创建了BaiduSpider类用来爬取数据
step4、爬虫文件内部写法
1、观察认识baiduSpider.py
Spider类下,有我们创建爬虫类使用的参数name、域名、start_urls如下图。这里的start_urls由我自己来写。因为我们要爬取的是这些词条的页面,所以创建一个url列表即可。
2、可以自定义的start_urls
我的做法是从本地读文件,url列表传入start_urls
start_urls = []
file_object=open('psycho_terms.txt', 'r').read()
wordList=file_object.split() #获取词表
#构造初始地址列表
for i in wordList: ##生成url列表
# cur = "http://www.baike.com/wiki/"
cur = 'https://baike.baidu.com/item/'
cur = cur + str(i)
start_urls.append(cur)
3、parse函数的写法
对想要抓取的item内容使用xpath表示,以本项目为例:
#爬取详细信息 detail=response.xpath("string(//div[@class='lemma-summary'])").extract()[0].strip()
detail=detail.replace('\r', '').replace('\t', '').replace('\xa0', ' ').replace('\n', '')
item['detail']=detail
yield item
解析:string表示抓取标签下所有文本,包括子标签下的文本
测试parse中print的结果命令:$ scrapy crawl baiduSpider --nolog
个人经验:在parse函数中可以使用print输出可以用来调试。
注:此命令执行后,如果settings.py里的ITEM_PIPELINES没有被解开注释,就不会调用pipline.py,就没有输出到item。
4、使用pipline输出
爬虫文件的功能(包括parse函数)测试过后,就要按照自定义规则写出到本地了。
首先需要解禁pipline,在settings.py文件中有一段:
ITEM_PIPELINES = {
'psySpider.pipelines.PsyspiderPipeline': 300,
}
打开注释,那么$ scrapy crawl baiduSpider --nolog
命令就会对pipline生效。
函数写法:
期间遇到一个坑在additi里有描述,这个pipline类的关键函数还是process_item():
def process_item(self, item, spider):
#设置每行要写的内容
l = str(self.count)+" "+str(item["title"])+" "+str(item["url"])+" "+" "+str(item["detail"])+"\n" # " "+str(item["title"])+" "+str(item["url"])+" "+
#此处输出,方便程序的调试
print("检测输出l:")
print(l)
#将对应信息写入文件中
self.file.write(l)
self.count+=1
return item
*addition、个人工作记录整理
此段为自己工作记录整理,内容乱,可以略过直接看step4。
2、测试baiduSpider.py内部的parse
3、使用pipline存储文件时遇到的坑
如图,在piplines.py文件内的init()函数下创建file后,在process_item中有一行是往文件里写内容,可运行之后发现print(l)
这一行会在终端显示我爬取的结果,可问题是哪里都找不到crawed_details.txt文件(自己手动创建一个结果也不会写入),最后在参考别人代码时候发现问题,原来是init()没有写成__init__()
。这里注意,startproject命令产生的piplines文件中init需要修改成__int__.
写好sparse后,测试命令是scrapy crawl baiduSpider --nolog