吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5900|回复: 44
收起左侧

[Python 转载] python写的一个GUI界面的小说爬虫软件

  [复制链接]
banro512 发表于 2022-2-7 16:53
一个小说爬虫,带GUI界面
主要功能

1.  多线程爬取
2.  可使用代{过}{滤}理
3.  实时输出过程
4.  一本书一个txt文件

1.png
2.png
3.png

全部源码

[Python] 纯文本查看 复制代码
import time
import requests
import os
import re
import random
from lxml import etree
import webbrowser
import PySimpleGUI as sg
import threading


# user-agent
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"
}
# 代{过}{滤}理
proxies = {}
# 删除书名中特殊符号
# 笔趣阁基地址
baseurl = 'https://www.xbiquwx.la/'
# 线程数量
threadNum = 6
pool_sema = None
THREAD_EVENT = '-THREAD-'
cjstatus = False

# txt存储目录
filePath = os.path.abspath(os.path.join(os.getcwd(), 'txt'))
if not os.path.exists(filePath):
    os.mkdir(filePath)

# 删除特殊字符
def deletetag(text):
    return re.sub(r'[\[\]#\/\\:*\,;\?\"\'<>\|\(\)《》&\^!~=%\{\}@!:。·!¥……() ]','',text)

# 入口
def main():
    global cjstatus, proxies, threadNum, pool_sema
    sg.theme("reddit")
    layout = [
        [sg.Text('输入要爬取的小说网址,点此打开笔趣阁站点复制', font=("微软雅黑", 12),
                 key="openwebsite", enable_events=True, tooltip="点击在浏览器中打开")],
        [sg.Text("小说目录页url,一行一个:")],
        [
            sg.Multiline('', key="url", size=(120, 6), autoscroll=True, expand_x=True, right_click_menu=['&Right', ['粘贴']]
                         )
        ],
        [sg.Text(visible=False, text_color="#ff0000", key="error")],
        [
            sg.Button(button_text='开始采集', key="start", size=(20, 1)),
            sg.Button(button_text='打开下载目录', key="opendir",
                      size=(20, 1), button_color="#999999")
        ],
        [sg.Text('填写ip代{过}{滤}理,有密码格式 用户名:密码@ip:端口,无密码格式 ip:端口。如 demo:123456@123.1.2.8:8580')],
        [
            sg.Input('', key="proxy"),
            sg.Text('线程数量:'),
            sg.Input('5', key="threadnum"),
        ],
        [
            sg.Multiline('等待采集', key="res", disabled=True, border_width=0, background_color="#ffffff", size=(
                120, 6), no_scrollbar=False, autoscroll=True, expand_x=True, expand_y=True, font=("宋体", 10), text_color="#999999")
        ],
    ]
    window = sg.Window('采集笔趣阁小说', layout, size=(800, 500), resizable=True,)
    while True:
        event, values = window.read()
        if event == sg.WIN_CLOSED or event == 'close':  # if user closes window or clicks cancel
            break
        if event == "openwebsite":
            webbrowser.open('%s' % baseurl)
        elif event == 'opendir':
            os.system('start explorer ' + filePath)
        elif event == 'start':
            if cjstatus:
                cjstatus = False
                window['start'].update('已停止...点击重新开始')
                continue
            window['error'].update("", visible=False)
            urls = values['url'].strip().split("\n")
            lenth = len(urls)
            for k, url in enumerate(urls):
                if (not re.match(r'%s\d+_\d+/' % baseurl, url.strip())):
                    if len(url.strip()) > 0:
                        window['error'].update("地址错误:%s" % url, visible=True)
                    del urls[k]

            if len(urls) < 1:
                window['error'].update(
                    "每行地址需符合 %s84_84370/ 形式" % baseurlr, visible=True)
                continue
            # 代{过}{滤}理
            if len(values['proxy']) > 8:
                proxies = {
                    "http": "http://%s" % values['proxy'],
                    "https": "http://%s" % values['proxy']
                }
            # 线程数量
            if values['threadnum'] and int(values['threadnum']) > 0:
                threadNum = int(values['threadnum'])
            pool_sema = threading.BoundedSemaphore(threadNum)
            cjstatus = True
            window['start'].update('采集中...点击停止')
            window['res'].update('开始采集')

            for url in urls:
                threading.Thread(target=downloadbybook, args=(
                    url.strip(), window,), daemon=True).start()
        elif event == "粘贴":
            window['url'].update(sg.clipboard_get())

        print("event", event)
        if event == THREAD_EVENT:
            strtext = values[THREAD_EVENT][1]
            window['res'].update(window['res'].get()+"\n"+strtext)
    cjstatus = False
    window.close()

#下载
def downloadbybook(page_url, window):
    try:
        bookpage = requests.get(url=page_url, headers=header, proxies=proxies)
    except Exception as e:
        window.write_event_value(
            '-THREAD-', (threading.current_thread().name, '\n请求 %s 错误,原因:%s' % (page_url, e)))
        return
    if not cjstatus:
        return
    # 锁线程
    pool_sema.acquire()

    if bookpage.status_code != 200:
        window.write_event_value(
            '-THREAD-', (threading.current_thread().name, '\n请求%s错误,原因:%s' % (page_url, page.reason)))
        return

    bookpage.encoding = 'utf-8'
    page_tree = etree.HTML(bookpage.text)
    bookname = page_tree.xpath('//div[@id="info"]/h1/text()')[0]
    bookfilename = filePath + '/' + deletetag(bookname)+'.txt'
    zj_list = page_tree.xpath(
        '//div[@class="box_con"]/div[@id="list"]/dl/dd')
    for _ in zj_list:
        if not cjstatus:
            break
        zjurl = page_url + _.xpath('./a/@href')[0]
        zjname = _.xpath('./a/@title')[0]
        try:
            zjpage = requests.get(
                zjurl, headers=header, proxies=proxies)
        except Exception as e:
            window.write_event_value('-THREAD-', (threading.current_thread(
            ).name, '\n请求%s:%s错误,原因:%s' % (zjname, zjurl, zjpage.reason)))
            continue

        if zjpage.status_code != 200:
            window.write_event_value('-THREAD-', (threading.current_thread(
            ).name, '\n请求%s:%s错误,原因:%s' % (zjname, zjurl, zjpage.reason)))
            return 
        
        zjpage.encoding = 'utf-8'
        zjpage_content = etree.HTML(zjpage.text).xpath('//div[@id="content"]/text()')
        content = "\n【"+zjname+"】\n"
        for _ in zjpage_content:
            content += _.strip() + '\n'
        with open(bookfilename, 'a+', encoding='utf-8') as fs:
            fs.write(content)
            window.write_event_value(
                '-THREAD-', (threading.current_thread().name, '\n%s:%s 采集成功' % (bookname, zjname)))
        time.sleep(random.uniform(0.05, 0.2))

    # 下载完毕
    window.write_event_value('-THREAD-', (threading.current_thread(
    ).name, '\n请求 %s 结束' % page_url))
    pool_sema.release()


if __name__ == '__main__':
    main()




使用方法

1. 首先要配置好 python3 环境,
2.  新建一个空目录,在此目录下新建 start.py 文件,将源码复制在 start.py 文件内
3.  在此目录下打开 cmd.exe,执行命令  python -m venv   .
4.  分别执行
pip install requests
pip install pysimplegui
pip install lxml
pip install pyinstaller

5. 在执行  pyinstaller -Fw start.py
结束后就能在 dist 下看到 exe


已打包好的 exe 文件下载

链接: https://pan.baidu.com/s/10FcAcJjKHmv8Blx3evX4TQ?pwd=3v6h 提取码: 3v6h 复制这段内容后打开百度网盘手机App,操作更方便哦

免费评分

参与人数 10吾爱币 +10 热心值 +10 收起 理由
greynet + 1 + 1 用心讨论,共获提升!
5ipj2007 + 1 + 1 谢谢@Thanks!
听雨长风 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
ccchpig + 1 + 1 我很赞同!
hkf369 + 1 + 1 热心回复!
52菜鸟 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
y_w_o + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
52mmm8888 + 1 + 1 https://wwe.lanzoul.com/iaFwJzpqkab 密码:52pj
good-idea + 1 + 1 鼓励一个,虽然我不看小说
yjn866y + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

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

开创者 发表于 2022-2-8 19:46
banro512 发表于 2022-2-8 18:36
看着没问题,错误应该不在这里
直接body   
然后div挨个试试看,有没有获取到内容

感觉问题还是在这儿。
[HTML] 纯文本查看 复制代码
zjpage_content = etree.HTML(zjpage.text).xpath('//div[@class="newsDel_main_m"]/dl/dd/text()')

我直接print(zjpage.text)可以得到整个网页的html
若print(etree.HTML(zjpage.text))得到的是
[HTML] 纯文本查看 复制代码
event start
<Element html at 0x3e822c8>
event -THREAD-
<Element html at 0x3e82388>
event -THREAD-
<Element html at 0x41e2508>

而我print(zjpage_content)得到的是
[HTML] 纯文本查看 复制代码
event start
['\r\n\r\n\t\t\t\t \r\n', '\r\n', '\r\n', '\r\n']
event -THREAD-
['\r\n\r\n\t\t\t\t \r\n', '\r\n', '\r\n', '\r\n']
event -THREAD-
['\r\n\r\n\t\t\t\t \r\n', '\r\n', '\r\n', '\r\n']
event -THREAD-

感觉问题还是在这一段代码里面
[HTML] 纯文本查看 复制代码
zjpage_content = etree.HTML(zjpage.text).xpath('//div[@class="newsDel_main_m"]/dl/dd/text()')

无论我xpath里加什么,都只能得到空白在txt里,难道是网站的问题?
从整个来看应该是没有问题的。现在看来有没有可能是网站的问题呢?
开创者 发表于 2022-2-8 17:44
banro512 发表于 2022-2-8 15:11
你的页面中存在 di=content 的 元素吗
xpath了解下

不在。
我的内在
[HTML] 纯文本查看 复制代码
<div class="newsDel_main_m">
<dl>
<dd>
文章内容
</dd>
</dl>
</div>

所以我给修改成了
[PHP] 纯文本查看 复制代码
zjpage_content = etree.HTML(zjpage.text).xpath('//div[@class="newsDel_main_m"]/dl/dd/text()')

这样操作对吗?
q13774972508 发表于 2022-2-7 17:15
多谢分享 最近也正准备学python  请多指教一二
wapj202022 发表于 2022-2-7 17:19
特别方便,下了。谢。。。
yjn866y 发表于 2022-2-7 17:50
yuyt学习学习
af8889 发表于 2022-2-7 17:51
转存了,也许能用上。谢谢楼主分享原创作品!
alstar 发表于 2022-2-7 18:05
多谢分享
fscm12 发表于 2022-2-7 18:07
非常好,感谢楼主
chaniug 发表于 2022-2-7 19:00
直接拿下
52菜鸟 发表于 2022-2-7 19:24
必须得有python环境吧
temp13 发表于 2022-2-7 19:26
正在学,mark 学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-4-25 12:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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