本帖最后由 山野村夫-陈墨 于 2019-10-22 00:00 编辑
由于朋友想看这本书,刚好不能下载,所以有了今年的故事。当然,如果人家不让爬,那这就是一场事故的前奏了。
这个暂且不谈,我们说说这个 程序。
结果哩,是这样的。
程序是这样的:
核心就是用到的是Xpath工具找到小说标题和内容。
[Python] 纯文本查看 复制代码 '''
爬取 小说天堂 《狼狗》 1-73章
第一章:https://www.xstt5.com/dangdai/4236/252445.html
最后一章:https://www.xstt5.com/dangdai/4236/252517.html
2019年10月20日
'''
import requests
from lxml import etree
import time
'''
请求网页数据,利用Xpath找到标题和内容
标题作为文件名
'''
def request(url):
header = {
"Referer":"https://uland.taobao.com/sem/tbsearch?refpid=mm_26632258_3504122_32538762&clk1=f165a3cac48d521b64f09db3154c2140&keyword=%E5%AE%89%E5%85%A8%E5%A5%97%20%E7%94%B7&minPrice=20&maxPrice=200&spm=a2e15.8261149.07626516001.dsortpricerange",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win32; x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
}
str = requests.get(url= url,headers = header)
str = etree.HTML(str.content.decode())
#获取标题
title_str = str.xpath("//*[@id=\"main\"]/div[1]/h1/text()")
#获取文章
news_str = str.xpath("//*[@id=\"main\"]/div[2]/text()")
#保存数据
f = open("狼狗/{}.txt".format(title_str[0]), "w+")
f.write(title_str[0])
f.write("\n\n")
for item in news_str:
f.write(item)
f.write("\n")
f.close()
print("{} is over".format(title_str[0]))
#设置睡眠时间,防止反爬
time.sleep(0.5)
def get_url(page_number):
url = "https://www.xstt5.com/dangdai/4236/{}.html".format(str(page_number))
print(url)
request(url)
def get_txt():
#url的部分数据范围
min_page=252445
max_page=252517
#请求10次数据再多休眠一次
number = 0
for p in range(min_page, max_page+1):
get_url(p)
number += 1
if(number % 10 == 0):
time.sleep(3)
if __name__ == "__main__":
get_txt()
问题呢 ?是这样的:
(1)没有异常处理机制,如果一不小心被反爬,那么后面的章节都会失败;
(2)单线程处理,真的很花时间;
(3)txt排版有问题。一行好几句话,阅读难受。
那么,下次,就处理这些问题。
/**************************************************************************************************************************************************************/
很好,定期完成任务。解决了上面是三个问题的程序出来了,不想充帖子数了,直接在 下面更新吧。
本次新添加的内容:
(1)异常处理机制,防止某一章的失败影响整个程序;
[Python] 纯文本查看 复制代码 try: print("running")
except BaseException:
pass
" BaseException"不管什么异常,都pass,
(2)多线程。一个线程爬取数据,一个线程处理txt文档。当然使用多线程,如果有共享变量就用到了互斥锁
threading.Lock(), 它有两个方法acquire()打开互斥锁,release()释放互斥锁。
[Python] 纯文本查看 复制代码 '''
爬取 小说天堂 《狼狗》 1-73章
第一章:https://www.xstt5.com/dangdai/4236/252445.html
最后一章:https://www.xstt5.com/dangdai/4236/252517.html
2019年10月20日
'''
import requests
from lxml import etree
import time
import threading
'''
第一部分
请求网页数据,利用Xpath找到标题和内容
标题作为文件名
'''
def request(url):
header = {
"Referer":"https://uland.taobao.com/sem/tbsearch?refpid=mm_26632258_3504122_32538762&clk1=f165a3cac48d521b64f09db3154c2140&keyword=%E5%AE%89%E5%85%A8%E5%A5%97%20%E7%94%B7&minPrice=20&maxPrice=200&spm=a2e15.8261149.07626516001.dsortpricerange",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win32; x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
}
str = requests.get(url= url,headers = header)
str = etree.HTML(str.content.decode())
#获取标题
title_str = str.xpath("//*[@id=\"main\"]/div[1]/h1/text()")
#获取文章
news_str = str.xpath("//*[@id=\"main\"]/div[2]/text()")
#保存数据
f = open("狼狗/原件/{}.txt".format(title_str[0]), "w+")
f.write(title_str[0])
f.write("\n\n")
for item in news_str:
f.write(item)
f.write("\n")
f.close()
#打开互斥锁
lock.acquire()
title_list.append(title_str[0]+".txt")
lock.release()
#释放互斥锁
print("{} is over".format(title_str[0]))
#设置睡眠时间,防止反爬
time.sleep(0.5)
def get_url(page_number):
try:
url = "https://www.xstt5.com/dangdai/4236/{}.html".format(str(page_number))
print(url)
request(url)
except BaseException:
pass
def get_txt():
#url的部分数据范围
min_page=252445
max_page=252517
#请求10次数据再多休眠一次
number = 0
for p in range(min_page, max_page+1):
get_url(p)
number += 1
if(number % 10 == 0):
time.sleep(3)
'''
第二部分
重新修改txt文档格式
'''
def rewrite_txt(name_txt):
with open("狼狗/修改/{}".format(name_txt), "w") as outf:
with open("狼狗/原件/{}".format(name_txt),"r") as inf:
while True:
tmp_str = inf.readline()
if not tmp_str:
break
while(tmp_str[:60]):
outf.write(tmp_str[:60])
if tmp_str[:60][0]!='\n':
outf.write("\n")
tmp_str = tmp_str[60:]
def get_txt_name():
try :
'''
次数读取第一个元素的理由是:避免读取的数据和删除的数据不一致
(1)列表没有元素,读取时索引异常,不进行删除;
(2)列表有元素,读取到元素title_list[0],request()即使添加元素,也会添加到title_list[0]后面
'''
name_str = title_list[0]
del title_list[0]
return name_str
except BaseException:
pass
return None
def rewrite():
while True:
name_txt = get_txt_name()
print(name_txt)
if name_txt:
rewrite_txt(name_txt)
else:
time.sleep(3)
if len( threading.enumerate()) == 2 and len(title_list) == 0:
break
#标题列表,保存爬到的小说标题
title_list = []
#互斥锁
lock = threading.Lock()
if __name__ == "__main__":
threading.Thread(target=get_txt).start()
#首先爬取数据
time.sleep(3)
threading.Thread(target=rewrite).start()
|