找到一本小说,但是下载需要会员。不想冲会员,所以想爬下来。再次同时发现一个资源很多的网站,八零小说网。所以写了一个爬虫,把书爬下来。
首先,打开想下载的小说的章节列表界面:
然后获取每章的链接:
八零小说网不对请求做限制,可以直接requests获取响应。
def parse_list(response):
x = etree.HTML(response.text)
return [''.join(i) for i in x.xpath('//div[@id="yulan"]/li/a/@href')]
为了不对对方的服务器造成影响。对每章的URL列表进行切分。
def split_list(li):
# 60个一份
res = []
split = []
for i in range(1,len(li)+1):# 包前不包后
if i%50 == 0:
split.append(li[i-1])
res.append(split)
split = []
else:
split.append(li[i-1])
if i == len(li):
split.append(li[i-1])
res.append(split)
return res
下面开始下载:使用gevent协程包提高效率。
def parse_content(li):
res = [gevent.spawn(get_content,i) for i in li]
gevent.joinall(res)
for i in res:
r = i.value
r.encoding = 'gbk'# 目标网站的源码中提到数据格式是gbk
x = etree.HTML(r.text)
title = x.xpath('//div[@class="date"]/h1/text()')
content = x.xpath('//div[@class="book_content"]/text()')
save(list2unicode(title)+'\n'+list2unicode(content).replace(' ','\n '))
# 其中list2Unicode是将列表转换成Unicode
保存到本地txt
def save(string):
with open('/path/to/file.txt','a') as file:
file.write(string.encode('utf-8'))
file.close()
主函数:
def main():
url = 'http://www.80txt.com/txtml_54887.html'
url_list = parse_list(get_content(url))
for i in split_list(url_list):
parse_content(i)
print '等待10s'
time.sleep(10)
我设置了等待10秒
但是实际效率大概是
一共13个块,每个块大概1.5s 一共20秒左右。
当然,如果gevent设置成一个快的话,就是2秒左右。
不过,强烈不建议。爬虫不是性能测试。