Python爬虫爬取小说

近来闲的无聊,天天逛CSDN看到python多火热多火热,就自己根据教程学习爬虫,参考了好几个博文,忘了地址是啥就不贴出来了

开发工具:PcCharm

开发环境:Python3.8

这次爬取的小说网站是:http://www.xiaoshuo240.cn/cbxs240/1230/ ,因为网页结构简单好爬取!!话不多说上代码!!

(1).先观察一下页面结构,我们需要的是 a标签里的href链接,但是这里的链接不全,需要拼接上网站的域名

查找连接的正则可以这么写    r"<dd><a href='(.*?)'>(.*?)</a></dd>" .*?代表匹配所有;(.*?)加上括号代表这个值是我们需要的会出现在结果集中

写法:

# 正则
charpet_reg = r"<dd><a href='(.*?)'>(.*?)</a></dd>"
#编译一下执行更快
charpet_reg = re.compile(charpet_reg)
#findall会匹配到页面中所有符合正则的内容 
urls = re.findall(charpet_reg,charpet_html)

再来看看每个章节的正文,他们都是包在<div id="content"></div>中,文中有许多<br>换行,所以正则要这么写

r'<br/>([\s\S]*?)</div>'  其中 [\s\S]代表换行

话不多说上代码,可以直接运行的

import urllib.request
import re
#Reptile.Util 是我自己写的一个工具包
import Reptile.Util
import time

def getContent():
    # hearders是为了伪装自己,假装成浏览器去访问页面,可以降低被封ip的几率
    headers = {'User-Agent': 'User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'}
    #这是本次爬取得目标
    url = "http://www.xiaoshuo240.cn/cbxs240/1230/";
    charpet_html = urllib.request.Request(url,headers=headers);
    charpet_html = urllib.request.urlopen(charpet_html).read()
    #对页面的内容进行转码,不然是乱码
    charpet_html = charpet_html.decode('utf-8','ignore')
    
    # 正则 
    charpet_reg = r"<dd><a href='(.*?)'>(.*?)</a></dd>"
    #re.compile编译一下 执行快
    charpet_reg = re.compile(charpet_reg)
    #re.findall就查找到我们需要的内容了
    urls = re.findall(charpet_reg,charpet_html)
    #查看工作日志 看上次下载到第几条了
    file_content = Reptile.Util.getWorkLog()
    if file_content != '':
        print('上次下载到:',file_content)
    x = 0
    y = 0
    for url in urls:
        novel_url = url[0]
        #从href取出的url不能直接用,需要拼接上笔趣阁的域名
        novel_url = 'http://www.xiaoshuo240.cn%s'%novel_url
        #把英文的:和英文的?替换成中文的了,因为之前碰到报错了
        novel_name = url[1].replace(':', ':').replace('?', '?')
        if y == 0 and x == 0 :
            #如果日志是空的就进行章节判断
            if file_content == '':
                # 因为笔书阁会把最近更新的章节放到前面,所以要过滤一下,从第一章开始爬取
                if novel_url[-7::] != '/1.html' and x == 0:
                    continue
                else:
                    x=1
            else:
                #如果日志不是空的,就要判断上次爬到哪个章节,接着爬取
                if novel_url == file_content:
                    y = 1
                    continue
                else:
                    continue
        print('tite:', novel_name, ';address:', novel_url)
        #获取每个章节的页面
        novel_html = urllib.request.Request(novel_url,headers=headers)
        novel_html = urllib.request.urlopen(novel_html).read()
        novel_html = novel_html.decode('utf-8','ignore')
        # 正则  文章中很多换行符 要使用[\s\S]。([\s\S]*?)这里获取到的就是正文了 
        novel_reg = re.compile(r'<br/>([\s\S]*?)</div>')
        novels = re.findall(novel_reg,novel_html)
        for novel in novels:
            #把正文里面的空格换行给替换掉
            novel = novel.replace('&nbsp;','').replace('<br/>','\n\t').replace('<br />','\n\t').replace('<p>笔趣阁(m.xiaoshuo240.cn)希望你喜欢书迷们第一时间分享的尘骨最新章节内容,如果有错误内容和字体欢迎点击章节报错!喜欢请收藏我们官网:m.xiaoshuo240.cn</p>','')
            novel_save = open('尘骨/%s.txt'%novel_name,'w')
            novel_save.write(novel)
            #记录本次执行到哪一章节
            Reptile.Util.saveWorkLog(novel_url)
        #休息3秒 访问太频繁会被封ip的
        time.sleep(3)
    novel_save.close()
getContent()

还有一个简单的工具类

import os

# 判断文件路径是否存在,不存在则创建
def checkPath(path):
    isExists = os.path.exists(path)
    if not isExists:
        os.makedirs(path)

# 保存工作日志
def saveWorkLog(workLog):
    checkPath('尘骨')
    file = open('尘骨/log.txt','w+')
    # 定位到文件开头
    file.seek(0,0)
    #清空文件
    file.truncate()
    file.write(workLog)
    file.close()

# 获取工作日志
def getWorkLog():
    isExists = os.path.exists('尘骨/log.txt')
    if True == isExists:
        file = open('尘骨/log.txt','r')
        file_content = file.read()
        file.close()
        return file_content
    else:
        return ''

需要注意的就是我这两个文件都是在项目下的Reptile文件下,所以引入Util的时候,写的是 import Reptile.Util,大家根据自己的路径自行修改!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值