刚才我们都是把抓取结果输出到了控制台上,关闭窗口后,这些记录就没有了。
如何保存爬虫辛辛苦苦抓取来的结果呢?这时候,我想到了文件……
为啥不用数据库啊?因为连接MySql数据库太麻烦,还不如文件来的直接方便。数据库删除的时候还得写delete * from XXX where 1
,我懒……文件多好,直接删掉就OK了。
更关键的,数据库,怎么的不得再起动个服务啊?即使是sqli这样的轻量级数据库……你能直接拿记事本打开么?嘎嘎~~
封装文件读写
Python给我们封装了文件的操作。我们可以像这样对其进行二次封装,更方便使用:
class Saver:
def __init__(self, path='./', filename='result.txt', method='w+'):
self.path = path
self.filename = filename
self.method = method
# 打开的文件
self.FILE = 'Unknown'
def open(self):
self.FILE = open(self.path + self.filename, self.method)
def write(self, data):
self.FILE.write(data)
def close(self):
self.FILE.close()
感觉这样封装意义不是太大哈……
直接输出为CSV文件
上面直接操作文件是很方便,但是!我想让获取到的东西直接做成一个Excel,或者简单一点,一个CSV文件。这样就能用Excel很快地进行操作了(比如排序啊,做个统计图啊什么的)。
工具就是拿来为我们服务的嘛……
所以我们可以对Python的excel读写类和CSV读写类做类似下面这样的封装:
class CsvSaver:
def __init__(self, path='./', filename='result.txt', method='w+'):
self.path = path
self.filename = filename
self.method = method
# 打开的文件
self.FILE = None
self.WRITER = None
def open(self):
self.FILE = open(self.path + self.filename, self.method)
self.WRITER = csv.writer(self.FILE, quoting=csv.QUOTE_ALL)
def write(self, data):
'参数是一个list'
self.WRITER.writerow(data)
self.FILE.flush()
def close(self):
self.FILE.close()
这样的话封装就好一点了。
注意,我的逻辑是,有一个数据要写,那么就立刻从缓冲区里面flush出来。虽然加大了io,但是万一万一程序崩溃掉了,缓冲区里面地东西都能被及时保存出来啊~不会“丢数据”。
为什么不直接输出成xls或者xlsx文件?因为我懒……没看懂官方doc。就这样吧,够用就好。
代码变长了……
我的思路很奇怪:如果某个网页获取成功,那么我将获取到的信息输出到一个文件里面;如果这个网页获取失败,那么将失败的原因输出到另一个文件里面,以备以后心血来潮复查。
于是,我们的代码变成了这样:
import csv
import requests
from bs4 import BeautifulSoup
class CsvSaver:
def __init__(self, path='./', filename='result.txt', method='w+'):
self.path = path
self.filename = filename
self.method = method
# 打开的文件
self.FILE = None
self.WRITER = None
def open(self):
self.FILE = open(self.path + self.filename, self.method)
self.WRITER = csv.writer(self.FILE, quoting=csv.QUOTE_ALL)
def write(self, data):
'参数是一个list'
self.WRITER.writerow(data)
self.FILE.flush()
def close(self):
self.FILE.close()
class Spider:
def __init__(self, dataSaver, failSaver=None):
self.queue = []
self.dataSaver = dataSaver
self.failSaver = failSaver
def addUrlBlock(self, start=100, end=200):
for index in range(start, end):
url = 'http://www.lagou.com/gongsi/' + str(index) + '.html'
self.addUrl(url)
def addUrl(self, url):
self.queue.append(url)
def run(self):
self.dataSaver.open()
if self.failSaver:
self.failSaver.open()
while self.queue:
url = self.queue.pop(0)
try:
response = requests.get(url, timeout=5, allow_redirects=False)
data = BeautifulSoup(response.text)
name = data.h1.a.text.strip()
location = data.find('ul', 'info_list_with_icon').find(attrs={'class': 'location'}).span.text
self.dataSaver.write([name, location])
print("Success %s" % url)
except:
self.failSaver.write(["Fail", url])
self.dataSaver.close()
if self.failSaver:
self.failSaver.close()
if __name__ == '__main__':
dataStore = CsvSaver(filename='result.csv')
logStore = CsvSaver(filename='log.csv')
spider = Spider(dataSaver=dataStore, failSaver=logStore)
spider.addUrlBlock(100, 200)
spider.run()
print('全部完成')
调理还算清晰吧?
小插曲
周日太累了,没有更新。昨天晚上,一个保存按下去,整个电脑卡掉了。卡回来发现,整个系统都只读了。关机关不住,强行断电、重启,直接进入Ubuntu的紧急模式了。
这不会修啊……重装吧。忘了当初UEFI启动的时候还顺带加载了Legzcy起动的相关东西,这次一直弄不好UEFI起动。好容易装上了,挂载/home
发现挂载不上,还是一直进入紧急模式。今天早上全盘备份,全盘格式化,重装到现在……然而到现在Matlab这个大家伙都还没有装。一直解压缩失败。
发表回复