吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12914|回复: 28
收起左侧

[Python 转载] 知轩藏书精校小说网全站爬虫

  [复制链接]
xiaomayi2012 发表于 2020-10-15 20:58
本帖最后由 xiaomayi2012 于 2021-6-6 21:22 编辑

这个爬虫是去年写的爬取 知轩藏书 网的一个爬虫,看论坛也有人分享这个网站的爬虫,我这个是去年7月份写的,代码有些乱,但主要功能都有,当时为了建小说站搞的,也没搞起来,今天整理硬盘时发现的,所以今天就分享出来,供大家交流学习,代码写的不是很严谨,很多冗余,可以根据喜好自行增删,大佬可以飘过~!以下代码仅供学习交流!废话不多说先上图:

20201015200455.jpg
20201015203900.jpg 20201015203923.jpg

本爬虫是直接爬取全站包括 小说简介 、图片、小说压缩包, 不能单独下载某一本小说,自己也懒得写了,需要的可以自己再添加,今天试了试代码可以正常运行,环境用的python 3.7 ,下面代码奉上:
【注意】:运行程序的时候一定要切换到程序根目录运行,根据下方的结构图建目录。
0、文件结构:
[HTML] 纯文本查看 复制代码
E:/zxcs
│——  zxcs.py
│
└─common
    │ —— config.ini
    │ —— DeHTMLParser.py
    │


1、主程序:zxcs.py
[Python] 纯文本查看 复制代码
import requests
import random
from lxml import etree
from common.DeHTMLParser import html_toText
import os
import time
import re


base_url = 'http://www.zxcs.me/sort/{}'

page = "/page/{}"
user_agent_list = [
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
]
UA = random.choice(user_agent_list)
HEADERS = {'User-Agent': UA}

# 简单封装网络请求操作

def get_requests(url):
    global NETWORK_STATUS
    NETWORK_STATUS = True  # 判断状态变量
    try:
        req = requests.get(url, headers=HEADERS, timeout=20)
        if req.status_code == 200:
            html = req.text
            return html
    except requests.exceptions.Timeout:
        NETWORK_STATUS = False  # 请求超时改变状态
        if not NETWORK_STATUS:
            '''请求超时'''
            for i in range(1, 10):
                print('请求超时,第%s次重复请求' % i)
                req = requests.get(url, headers=HEADERS, timeout=5)
                if req.status_code == 200:
                    html = req.text
                    return html
    return -1


# 获取各分类列表页中的总页数

def getPageTotal(cates):
    #base_url = "http://www.zxcs.me/sort/25/"
    req = get_requests(base_url.format(cates))
    selector = etree.HTML(req)
    page = selector.xpath("//*[@id='pagenavi']/a/@href")[-1].split('/')[-1]  # 获取每个分类下的总页数

    return page

# 获取每个分类下每页内容

def getPage(category, pageIdex):
    req = get_requests(base_url.format(category) + page.format(str(pageIdex)))
    return req


# 获取列表中文章的url

def getList(cates, pageIdex):
    req = getPage(cates, pageIdex)
    selector = etree.HTML(req)
    url_list = selector.xpath("//*[@id='plist']/dt/a/@href")

    return url_list


# 获取下载链接

def get_downUrl(url):
    link_id = url.split('/')[-1]  # 通过传入的文章地址截取网址中的文章id
    req = get_requests("http://www.zxcs.me/download.php?id={}".format(link_id))
    selector = etree.HTML(req)
    d_url = selector.xpath("//span[@class='downfile']/a/@href")[0]
    return d_url


# 下载小说

def saveRAR(url,fileName):
    print("开始下载",fileName,"小说...\n")
    rar_name = url.split('/')[-1]  # 截取网址中小说名称
    names = fileName + '/' + str(rar_name) #组合下载路径
    start = time.time()#开始时间
    size = 0
    req = requests.get(url,stream = True,headers=HEADERS)
    chunk_size = 1024 #每次下载的数据大小
    content_size = int(req.headers['content-length'])#总大小

    if req.status_code==200:
        print('[文件大小]:%0.2f MB' %(content_size / chunk_size /1024))#换算单位并print()
        with open(names,'wb') as f:
            for d in req.iter_content(chunk_size=chunk_size): # 获取请求的原始响应
                f.write(d)
                size += len(d)#已下载文件大小
                print('\r'+'[下载进度]:%s %.2f%%' % ('>'*int(size*50/ content_size),float(size/ content_size*100)),end='')
            f.close()

        end = time.time()
        print('\n',"小说下载完成!用时%.2f秒"%(end-start))

# 保存内容简介

def saveBrief(content,name):
    fileName = name + "/" + name + ".txt"
    f = open(fileName,"w+")
    print("正在偷偷保存小说简介",fileName)


    f.write(content)
# 保存内容页中图片到本地

def saveImg(imgUrl,fileName):
    name = imgUrl.split('/')[-1]
    req = requests.get(imgUrl).content
    if name.endswith(".jpg"):
        names = fileName + "/" +str(name)
    else:
        names = fileName+"/"+str(name.split('?')[0])

    f = open(names,'wb')
    f.write(req)
    print("正在悄悄的保存小说图片",name)
    f.close()


# 创建新目录

def mkdir(path):
    path = path.strip()
    # 判断路径是否存在
    # 存在     True
    # 不存在   False
    isExists=os.path.exists(path)
    # 判断结果
    if not isExists:
        # 如果不存在则创建目录
        print ("正在新建名为",path,'的文件夹')
        # 创建目录操作函数
        os.makedirs(path)
        return True
    else:
        # 如果目录存在则不创建,并提示目录已存在
        print("名为",path,'的文件夹已经创建!')
        return False


# 获取详情页内容并返回一个列表

def getContent(url):
    cont = []
    req = get_requests(url)
    selector = etree.HTML(req)
    title = selector.xpath("//*[@id='content']/h1/text()")[0]  # 标题
    category = selector.xpath("//*[@class='date']//a/text()")[1] #分类
    if len(selector.xpath("//*[@class='date']//a/text()"))>=3:
        tags = selector.xpath("//*[@class='date']//a/text()")[2] #分类
    else:
        tags ="暂无"
    if len(selector.xpath("//*[@id='content']/a/img/@src"))>0:
        image = selector.xpath("//*[@id='content']/a/img/@src")[0] # 图片
    elif len(selector.xpath("//*[@id='content']/img/@src"))>0:
        image = selector.xpath("//*[@id='content']/img/@src")[0] # 图片
    elif len(selector.xpath("//*[@id='content']/p/img/@src"))>0:
        image = selector.xpath("//*[@id='content']/p/img/@src")[0]
    else:
        image = selector.xpath("//*[@id='content']/p/a/img/@src")[0]  # 图片

    # print(image)
    text_info = selector.xpath("//*[@id='content']//p")[2]  # 获取内容页文本
    div_str = etree.tostring(text_info)  # 获取id中的html代码
    text = html_toText(div_str).strip().replace(' ', '')  # 调用外部工具类提取html中文本
    text = "".join(text.split("\xa0")) #去掉特殊字符\xa0

    cont.append(title)
    cont.append(image)
    cont.append(text)
    cont.append(category)
    cont.append(tags)
    cont.append(get_downUrl(url))
    return cont


# 保存一篇文章内容信息
'''
contents[0] 小说标题
contents[1] 小说封面图
contents[2] 小说简介
contents[3] 小说分类
contents[4] 小说下载地址
'''
def saveInfo(category,pageIndex):
    number = 1
    for ls in getList(category,pageIndex):
        contents = getContent(ls)
        mkdir(contents[0]) # 以文件名创建文件夹目录
        saveImg(contents[1],contents[0]) # 保存小说图片
        saveBrief(contents[4]+"\n\n"+contents[2],contents[0]) # 保存小说简介
        saveRAR(contents[5],contents[0]) # 下载小说附件
        print("\n------ 分类ID为",category,"的第",str(number),"部小说信息保存完毕 ------\n")
        number +=1


# 启动爬虫开始爬取数据

def runSpider(pageId,categroy):
    num = getPageTotal(categroy)# 获取每个分类下总页数
    for i in range(int(pageId), int(num) + 1):
        saveInfo(categroy,i)
        print("\n[--------- 第",i,"页爬取完毕!---------]\n")


if __name__ == '__main__':
    c = [23, 25, 26, 27, 28, 29, 55]
    # ss = get_page_total(base_url,23)
    # u = getList(23, 2)  # 获取页面中文章url
    # t = getContent("http://www.zxcs.me/post/1568")
    # u = get_downUrl("http://www.zxcs.me/post/11610")
    # print(t)
    '''
    都市生活  23    精校奇幻   38   精校灵异    41  精校竞技    44
    精校武侠  36    精校玄幻   39   精校历史    42  精校游戏    45
    精校仙侠  37    精校科幻   40   精校军事    43  二次元      55
    
    '''
    f = open("common/config.ini", encoding = 'utf-8')
    print(f.read())
    category = input("请输入您要爬取的分类:")

    pages = input("\n请输入您要爬取的开始页:")
    if len(category)>0 and len(pages)>0:
        print("\n爬虫启动中...")
        time.sleep(2)
        print("开始爬取数据...",time.strftime("%Y/%m/%d %H:%M:%S"))
        time.sleep(3)
        runSpider(pages,category) # runSpider(页码,分类号)
        # for p in c:
        print("分类",category,"爬取完毕!")


2、过滤Html标签的工具类代码:common/DeHTMLParser.py
[Python] 纯文本查看 复制代码
from html.parser import HTMLParser
from re import sub
from sys import stderr
from traceback import print_exc

"""
功能:将HTML提取为Text纯文本
"""
class DeHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.__text = []

    def handle_data(self, data):
        text = data.strip()
        if len(text) > 0:
            text = sub('[ \t\r\n]+', ' ', text)
            self.__text.append(text + ' ')

    def handle_starttag(self, tag, attrs):
        if tag == 'p':
            self.__text.append('\n\n')
        elif tag == 'br':
            self.__text.append('\n')

    def handle_startendtag(self, tag, attrs):
        if tag == 'br':
            self.__text.append('\n\n')

    def text(self):
        return ''.join(self.__text).strip()

def html_toText(text):
    try:
        parser = DeHTMLParser()
        parser.feed(text.decode())
        parser.close()
        return parser.text()
    except:
        print_exc(file=stderr)
        return text

def main():
    text = r'''
        <div id="info">导演: <a href="https://www.xl720.com/thunder/director/%e9%99%88%e7%bf%8a%e6%81%92" rel="bookmark">陈翊恒</a><br /> 编剧: <a href="https://www.xl720.com/thunder/writers/%e9%99%88%e7%bf%8a%e6%81%92" rel="bookmark">陈翊恒</a> / <a href="https://www.xl720.com/thunder/writers/%e6%a2%81%e9%b8%bf%e5%8d%8e" rel="bookmark">梁鸿华</a> / <a href="https://www.xl720.com/thunder/writers/%e5%ba%b8%e6%9d%90" rel="bookmark">庸材</a> / <a href="https://www.xl720.com/thunder/writers/%e8%94%a1%e7%b4%a0%e6%96%87" rel="bookmark">蔡素文</a><br /> 主演: <a href="https://www.xl720.com/thunder/stars/%e6%9e%97%e8%80%80%e5%a3%b0" rel="bookmark">林耀声</a> / <a href="https://www.xl720.com/thunder/stars/%e9%a9%ac%e5%bf%97%e5%a8%81" rel="bookmark">马志威</a> / <a href="https://www.xl720.com/thunder/stars/%e5%85%83%e7%a7%8b" rel="bookmark">元秋</a> / <a href="https://www.xl720.com/thunder/stars/%e8%91%9b%e6%b0%91%e8%be%89" rel="bookmark">葛民辉</a> / <a href="https://www.xl720.com/thunder/stars/%e9%bb%8e%e7%be%8e%e8%a8%80" rel="bookmark">黎美言</a> / <a href="https://www.xl720.com/thunder/stars/%e6%9d%a8%e6%9f%b3%e9%9d%92" rel="bookmark">杨柳青</a> / <a href="https://www.xl720.com/thunder/stars/%e5%91%a8%e6%ae%b7%e5%bb%b7" rel="bookmark">周殷廷</a> / <a href="https://www.xl720.com/thunder/stars/%e6%9e%97%e6%9b%89%e9%9b%af" rel="bookmark">林曉雯</a> / <a href="https://www.xl720.com/thunder/stars/%e5%bc%a0%e6%b2%9b%e4%b9%90" rel="bookmark">张沛乐</a> / <a href="https://www.xl720.com/thunder/stars/%e9%83%91%e4%b8%bd%e8%8e%8e" rel="bookmark">郑丽莎</a> / <a href="https://www.xl720.com/thunder/stars/%e6%9d%8e%e5%ae%97%e5%bd%a5"
rel="bookmark">宗彥</a> / <a href="https://www.xl720.com/thunder/stars/%e7%bd%97%e5%a4%a9%e6%b1%a0" rel="bookmark">罗天池</a> / <a href="https://www.xl720.com/thunder/stars/%e6%9d%8e%e9%80%b8%e6%9c%97" rel="bookmark">李逸朗</a><br /> 类型: 动作<br /> 制片国家/地区: <a href="https://www.xl720.com/thunder/area/xianggang" rel="bookmark">香港</a><br /> 语言: 粤语<br /> 上映日期: <a href="https://www.xl720.com/thunder/years/2019" rel="bookmark">2019</a>-03-19(中国大陆) / 2019-03-21(香港)<br /> 片长: 108分钟<br /> 又名: 格斗吧 / We Are Legends</div>
    '''
    print(html_toText(text))


if __name__ == '__main__':
    main()


3.配置文件:common/config.ini
[HTML] 纯文本查看 复制代码
==========================================================================
*                                                                        *
* 都市生活 【23】    精校奇幻 【38】   精校灵异 【41】   精校竞技 【44】 *
*                                                                        *
* 精校武侠 【36】    精校玄幻 【39】   精校历史 【42】   精校游戏 【45】 *
*                                                                        *
* 精校仙侠 【37】    精校科幻 【40】   精校军事 【43】   二次元   【55】 *
*                                                                        *
*=========================================================================

免费评分

参与人数 13吾爱币 +11 热心值 +13 收起 理由
woai2003 + 1 + 1 谢谢@Thanks!
lunker2019 + 1 + 1 谢谢@Thanks!
df5630693df + 1 + 1 我很赞同!
zz77244920 + 1 + 1 我很赞同!
chinawolf2000 + 1 + 1 热心回复!
千城忆梦 + 1 + 1 谢谢@Thanks!
江闪闪 + 1 谢谢@Thanks!
星辰一枚 + 1 热心回复!
woflant + 1 + 1 我很赞同!
永远只爱 + 1 + 1 我很赞同!
xiuji + 1 + 1 谢谢@Thanks!
showwh + 1 + 1 谢谢@Thanks!
fenz + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

花好s月圆 发表于 2020-10-15 22:00
还是用易语言post提交数据,更简单一点。
Natu 发表于 2020-10-16 00:58
Traceback (most recent call last):
  File "zxcs.py", line 4, in <module>
    from common.DeHTMLParser import html_toText
ModuleNotFoundError: No module named 'common.DeHTMLParser'
大侠,请问这个故障怎么排除?
aas8588729 发表于 2020-10-15 21:40
woflant 发表于 2020-10-15 22:12
感谢楼主分享
出现UnicodeDecodeError: 'gbk' codec can't decode byte 0x90 in position 169: illegal multibyte sequence错误
只需将
f = open("common/config.ini")
更改为
f = open("common/config.ini", encoding = 'utf-8')
即可
星辰一枚 发表于 2020-10-15 22:38
厉害了,感谢分享
玄非 发表于 2020-10-15 22:44
感谢分享
Natu 发表于 2020-10-15 23:30
爬虫横行……
Cypital 发表于 2020-10-15 23:30
厉害了,学习学习。
ciker_li 发表于 2020-10-16 08:48
学习学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表