通过python爬虫下载TXT文件,并整合到一个文件中

最近学习了下python爬虫,在简单看了一些文档之后就想着做点东西来完善下自己学习的内容。

因此就写了下面的代码,来实现把一个网站上面的小说内容下载下来。小说是一章一章的结构,因此在把每章的内容爬下来之后,还需要合并到一个TXT文件中。

python的版本是3.6,然后使用了beautifulsoup库。

 

网站的界面如下:

从上图可以看到,网站里面的内容每一章都是单独的下载链接。因此我需要把所有的文件合并到一起。经过查看页面的编码,发现为GBK编码,因此对下载到的文件,都需要通过GBK编码转换为字符串,然后写到最终文件中。

至于为什么我会把文件通过字符串的方式写到最终文件中,而不是通过字节码的方式,是因为考虑到为了能够把多个文件拼接到一起后,还考虑到文件的格式。比如每一章的名字,不同章之间能够有几个换行。方便我本地的一些靠小说的APP能够识别出小说的目录结构。

 

整体代码如下:

import urllib.request
import urllib.error
import re
from bs4 import BeautifulSoup
import time
import random


def download(url, user_agent='wswp', num_retries=2):
    print('downloading: %', url)
    # 防止对方禁用Python的代理,导致forbidden错误
    headers = {'User-agent': user_agent}
    request = urllib.request.Request(url, headers=headers)
    try:
        html = urllib.request.urlopen(request).read()
    except urllib.error.URLError as e:
        print('download error:', e.reason)
        html = None
        if num_retries > 0:
            # URLError是一个上层的类,因此HttpERROR是可以被捕获到的。code是HttpError里面的一个字段
            if hasattr(e, 'code') and 500 <= e.code < 600:
                return download(url, num_retries - 1)
    return html


def get_links(html):
    """
    return a list of links from html
    :param html:
    :return:
    """
    webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']')
    return webpage_regex.findall(html)


page_url = 'https://www.szyangxiao.com/txt197165.shtml'
html_result = download(page_url)

if html_result is None:
    exit(1)
else:
    # print(html_result)
    pass
# 分析得到的结果,从中找到需要访问的内容
# download_links = filter_download_novel_links(get_links(str(html_result)))
#
# for link in download_links:
#     print(link)
soup = BeautifulSoup(html_result, 'html.parser')
fixed_html = soup.prettify()

# print(fixed_html)

uls = soup.find_all('ul', attrs={'class': 'clearfix'})
lis = uls[1].find_all('li', attrs={'class': 'min-width'})

with open(r'F:\红楼之庶子风流.txt', 'w') as target_file_writer:
    for li in lis[340:]:
        a = li.find('a')
        href = a.get('href').replace('//', 'https://')
        text = a.text.replace('下载《红楼之庶子风流 ', '').replace('》txt', '')
        # print(text)
        # print(str(download(href), 'gbk'))
        target_file_writer.write(text)
        target_file_writer.write('\n')
        target_file_writer.write(str(download(href), 'gbk'))
        target_file_writer.write('\n')
        time.sleep(random.randint(5, 10))
        # print(text, href)

 

以上就是全部的需求和代码。当然不推荐看免费小说,以上代码只是只是为了一个实验。

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

本次对代码做了点改动。因为发现了不同系统下,比如英文系统环境下,通过字符串的方式写入文件会报错。因此我把代码改成了通过字节码的方式写到文件中。

 

# coding:utf-8
import urllib.request
import urllib.error
from bs4 import BeautifulSoup
import time
import random


# 使用LXML的方式来代替BeautifulSoup的方式


def download(url, user_agent='wswp', num_retries=2):
    print('downloading: %', url)
    # 防止对方禁用Python的代理,导致forbidden错误
    headers = {'User-agent': user_agent}
    request = urllib.request.Request(url, headers=headers)
    try:
        html = urllib.request.urlopen(request).read()
    except urllib.error.URLError as e:
        print('download error:', e.reason)
        html = None
        if num_retries > 0:
            # URLError是一个上层的类,因此HttpERROR是可以被捕获到的。code是HttpError里面的一个字段
            if hasattr(e, 'code') and 500 <= e.code < 600:
                return download(url, num_retries - 1)
    return html


page_url = 'https://www.szyangxiao.com/txt197165.shtml'
html_result = download(page_url)

if html_result is None:
    exit(1)
else:
    pass

# 分析得到的结果,从中找到需要访问的内容
soup = BeautifulSoup(html_result, 'html.parser')
fixed_html = soup.prettify()

uls = soup.find_all('ul', attrs={'class': 'clearfix'})
lis = uls[1].find_all('li', attrs={'class': 'min-width'})

# 修改文件写入方式为byte方式。
with open(r'C:\study\红楼之庶子风流.txt', 'wb') as target_file_writer:
    default_encode = 'utf-8'

    new_line = '\n'.encode(default_encode)

    for li in lis[340:]:
        a = li.find('a')
        href = a.get('href').replace('//', 'https://')
        # 把字符串转换成byte,然后写入到文件中
        text = a.text.replace('下载《红楼之庶子风流 ', '').replace('》txt', '').encode(default_encode)

        target_file_writer.write(text)
        target_file_writer.write(new_line)
        # 把字符串转换成byte,然后写入到文件中。因为源文件为gbk的编码方式,因此需要先decode,然后重新encode
        target_file_writer.write(download(href).decode('gbk').encode(default_encode))
        target_file_writer.write(new_line)
        time.sleep(random.randint(5, 10))

 

这样代码就适合运行在各种环境上了。

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是写一个爬取网页并整合成exe的Python代码: ```python # 导入需要的库 import requests import os import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit # 窗口类 class MyWindow(QWidget): def __init__(self): super().__init__() # 设置窗口大小和标题 self.setWindowTitle('网页爬虫') self.setGeometry(200, 200, 400, 300) # 添加控件 self.label_url = QLabel('网页地址:', self) self.label_url.move(50, 50) self.lineedit_url = QLineEdit(self) self.lineedit_url.move(120, 50) self.label_path = QLabel('保存路径:', self) self.label_path.move(50, 100) self.lineedit_path = QLineEdit(self) self.lineedit_path.move(120, 100) self.button_download = QPushButton('下载', self) self.button_download.move(150, 150) # 绑定按钮的点击事件 self.button_download.clicked.connect(self.download) # 下载网页的函数 def download(self): url = self.lineedit_url.text() path = self.lineedit_path.text() try: # 发送请求 response = requests.get(url) # 获取网页的内容 html = response.text # 保存网页的内容 with open(path, 'w', encoding='utf-8') as f: f.write(html) # 弹出保存成功的提示框 QMessageBox.information(self, '提示', '保存成功!') except Exception as e: # 弹出保存失败的提示框 QMessageBox.warning(self, '警告', str(e)) # 主函数 if __name__ == '__main__': # 创建应用程序对象 app = QApplication(sys.argv) # 创建窗口对象 window = MyWindow() # 显示窗口 window.show() # 运行应用程序 sys.exit(app.exec_()) ``` 以上代码使用了PyQt5库来创建了一个简单的图形界面,通过输入网页地址和保存路径,点击下载按钮来完成网页的下载。接下来将使用PyInstaller库将其整合成exe可执行文件。 1. 首先要确保已经安装了PyInstaller库,可以使用如下命令进行安装: ``` pip install pyinstaller ``` 2. 在命令行进入到Python程序所在的目录,使用如下命令生成.spec文件: ``` pyinstaller -w -F 程序名.py ``` 其-w参数表示不显示命令行窗口,-F参数表示生成单个可执行文件,程序名.py为要生成可执行文件Python程序名称。 3. 执行上一步后,会生成一个.spec文件,打开该文件,找到datas=[],修改为: ``` datas=[('路径/文件名.ui','.')] ``` 其路径/文件名.ui为程序的图形界面文件名称。 4. 使用如下命令进行编译: ``` pyinstaller -w -F 程序名.spec ``` 程序名.spec为上一步生成的.spec文件名称。 5. 编译完成后,在dist目录下会生成一个可执行文件,双击即可运行程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值