程序逻辑:按给出的第一章节URL,抓HTML,然后通过正则表达式,取出小说章节的 标题、正文、下章节的URL, 然后跳转到下一章节,不断循环处理。 取出的正文写入文本文件。 同时记录每次取过的URL,如果网络异常了,重启程序,可以从文件中取URL继续上次的抓取任务。
正则,对应如下图:
代码: https://download.csdn.net/download/fangkailove/11205946
#!/usr/bin/python # -*- coding: gbk -*- # by gnolux 20190526 # email: fangkailove@yeah.net from urllib import request import re import os import socket #socket.setdefaulttimeout(60) #第一章节的URL url = 'https://www.23us.la/html/203/203086/1130014.html' #URL前辍,用来拼接出下章节的绝对URL用 url_prex = 'https://www.23us.la/html/203/203086/' #取章节标题的正则表达式 title_match_str = r'<h1>(.*?)</h1>' #取章节正文的正则表达式 content_match_str = r'<div id="content">(.*?)</div>' #取下一章节URL的正则表达式(相对URL) next_page_match_str = r'<div class="link">.*?返回列表</a>→<a href="(.*?)">下一章</a>' #保存的文件名 save_file = 'd:/test/tclys.txt' #如果已经运行过,则记录了最后一次运行的下一面地址,从文件中取url last_url_file = '%s.url.txt'%save_file if os.path.isfile(last_url_file): with open(last_url_file, 'r') as f: url = f.read() headers = {'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'} #print(url) for page in range(0,99999999): req=request.Request(url=url,headers=headers) url = '' #如果timeout尝试重新提交,最多尝试8次 for t in range(0,8): try: response = request.urlopen(req,timeout=4) html = response.read() #print(html) html = html.decode("utf-8") title,content= '','' s=re.findall(title_match_str,html,re.S) if len(s) == 1: title=s[0] s=re.findall(content_match_str,html,re.S) if len(s) == 1: content = s[0] content=content.replace('<br/>','').replace(' ','').replace('<br />','') #print(title,content) with open(save_file, 'a',encoding='utf-8') as f: f.write("%s\n%s\n"%(title,content)) s=re.findall(next_page_match_str,html,re.S) if len(s) == 1: url = '%s%s'%(url_prex,s[0]) else: print(s) #记录下一章地址到文件,出现网络异常时,可以续传 with open(last_url_file, 'w') as f: f.write(url) #print('next url:%s'%url) print(title) #print(content) break;#成功则跳出重试。 except Exception as e: #抛出超时异常 print('第%d次尝试连接'%t, str(e)) if url == '': break;转载注明:转自 https://blog.csdn.net/fangkailove/article/details/90577174