使用scrapy爬取字幕文件建立聊天语料库
项目实训第5周快要结束了,最近进度有点慢,这一周多只搞了这个。使用scrapy爬取文件正好和web数据管理的实验有重合的要求,一箭双雕岂不美哉。
因为最终建立的程序为聊天机器人,想来想去,聊天对话最多的大量数据也就是字幕了。本来想爬取的网站为字幕库的,结果好巧不巧,就是最近,这个网站挂了。所以最终本次爬取的网站为 射手网(伪),把网页翻烂了,发现好爬的数据也就15页,200+个压缩包,先将就着用吧。
使用scrapy爬取文件
scrapy文件的创建在此不必多说了,我之前写了相应的如下:
聊天机器人——语料资源获取与词性分类。不过在此基础上,还有几个需要注意的地方。
setting.py文件修改
找到ITEM_PIPELINES,修改如下:
ITEM_PIPELINES = {
'zimu.pipelines.ZimuPipeline': 1,
}
在其后添加下载后装入文件的地址:
FILES_STORE = '../result/download/files'
item.py文件修改
给item类添加flies和file_urls,用于后续爬取结果的装入:
class ZimuItem(scrapy.Item):
files = scrapy.Field()
file_urls = scrapy.Field()
zimu_spider.py实现
因为比较好爬取的就是排行榜上的文件,这里我本来想把15页全爬下来,结果写的时候 for i in range(1, 15):
只爬取了前14页。
import scrapy
from ..items import ZimuItem
class ZimuSpiderSpider(scrapy.Spider):
name = 'zimu_spider'
allowed_domains = ['assrt.net/xml/list/sub']
start_urls = []
for i in range(1, 15):
start_urls.append('http://assrt.net/xml/list/sub/?page=' + str(i))
def parse(self, response):
hrefs = response.selector.xpath('//div[@class="subitem"]//a[contains(@id,"downsubbtn")]/@onclick').extract()
for url in hrefs:
url_detail = "https://assrt.net"+url[33:-15]
# dongt_filter必须设为true,不然可能因为屏蔽而无法爬取
request = scrapy.Request(url=url_detail, callback=self.parse_url, dont_filter=True)
yield request
def parse_url(self, response):
body = response.body
item = ZimuItem()
# 返回的url中取其中?前的就行了,虽然存在极少数错误,但不妨碍
url = response.url.split("?")[0]
item["file_urls"] = url
item["files"] = body
return item
修改文件pipelines.py
这个文件是很重要的,用于文件的下载写入,如下:
from scrapy.pipelines.files import FilesPipeline
class ZimuPipeline(FilesPipeline):
def process_item(self, item, spider):
url = item['file_urls']
file_name = url.replace('/', '_').replace(':', '_')
# print(file_name)
fp = open('../result/download/files/' + file_name, 'wb')
fp.write(item["files"])
fp.close()
return item
执行run.py
以上文件修改完之后就可以执行了,执行过程因为下载速度的原因需要一段时间,执行完毕后,可以在download/files/目录下看到200+文件等待处理。
对爬取文件进行初步的清理
爬取的文件中存在垃圾文件,我们需要处理后才方便后续使用,下面的文件以及需要用到的工具包,我放入了git仓库中。
correction.py删除错误格式文件
# 第一步
# 爬虫文件执行结束后,由于是使用split("?")进行文件判断命名,所以可能出现错误后缀,删除该文件即可
import os
path = "../result/download/files"
datanames = os.listdir(path)
for i in datanames:
bool1 = i.endswith(".zip")
bool2 = i.endswith(".rar")
if bool1 or bool2:
continue
else:
print(i)
os.remove(path+"/"+i)
unpack.py解压缩文件
# 第二步
# 解压缩文件,删除未成功压缩的文件
import zipfile
from unrar import rarfile
import os
path = "../result/download/files"
datanames = os.listdir(path)
for i in datanames:
bool1 = i.endswith(".zip")
bool2 = i.endswith(".rar")
if bool1:
try:
z = zipfile.ZipFile(path+"/"+i, '