利用pycharm(python)爬虫来下载一部网络小说

在家学了一段爬虫想分享一下自己的经验与心得,python新手水平拙劣语言水平有限望见谅

流程

爬取小说的主要步骤是:

  1. 获取目标数据(主页面和每一个章节)
  2. 分析数据加载(目标数据所对应的url)
  3. 获取目标数据(正则表达式匹配)
  4. 数据的清洗处理
  5. 下载数据保存到txt文件

准备工作

1.import requests(Python实现的简单易用的HTTP库);
2.import re(python的正则表达式功能);
3import json(JavaScript Object Notation)**;
4from requests.exceptions import RequestException
requess库的安装(pycharm):

打开pycharm的设置点击右上角的+号添加库

在这里插入图片描述

开始访问网站

定义一个函数,url当作参数
使用reques.get函数来获取网页数据
1.添加headers伪装服务器请求

headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'}

2.访问网站并判断是否访问成功(状态码)
通过状态码判断是否访问成功(200为访问成功并返回网页内容,失败返回None)

def get_url(url):
    try:
        headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'}
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None
url = 'https://www.ddxs.cc/ddxs/167986/'
html = get_url(url)


解析网页的html代码

引入正则表达式re.compile方法(通过正则表达式字符串生成表达式对象)

1.分析网站
查看网页源代码并分析每一章地址名称具有的共同代码
在这里插入图片描述
2.正则匹配所有章节的名称与地址

re.S的匹配模式为匹配所有(换行符与空格)
使用re.findall开始匹配,其中pattern为匹配模式,html为匹配的目标网站,也就是使用get_url(url)方法得到的结果

def parse_html(html):
    pattern = re.compile('.*?<dd><a href="(.*?)">(.*?)</a></dd>.*?',re.S) #定义正则表达方法来匹配每一章的名称与地址
    items = re.findall(pattern,html) #获取所有章节的信息得到一个列表
    print(items) #打印结果

将两个函数方法依次运行可得下列结果
在这里插入图片描述

for循环每一个章节并获取其中的小说内容

先将列表中每一章的地址与标题名称表示出来

    for item in items:
        title = item[1]
        http = item[0]
        each_http = 'https://www.ddxs.cc%s'%http

最重要的一步:分别访问每一章小说并将其中的内容提取出来

随便打开一章查看源代码,依旧使用正则表达式:
使用正则匹配时,要求开头与结尾都是唯一,这样匹配的结果才会准确,判断是否唯一的方法可以用ctrl+f搜索判断。同时开头与结尾最好靠近小说正文,这样匹配到的无关内容减少,方便后期数据的处理
在这里插入图片描述

    for item in items: #item代表每一章的内容与地址
        title = item[1] #每一章的标题
        http = item[0]  #每一章的地址
        each_http = 'https://www.ddxs.cc%s'%http #完整的每一章的地址
        each_pattern = re.compile('<div id="content">(.*?)<script>read3\(\);</script>.*?' ,re.S)  #确定匹配的规则
        content = str(re.findall(each_pattern,get_url(each_http))) #第二个参数为匹配的对象,也就是要用get_url函数分别访问每一章的地址
        print(content) #打印结果

对小说正文进行数据清洗并写入txt文件

数据清洗
在提取每一章的时候我对content进行了str字符串化,这是因为提取到的小说正文往往会有换行符等其他html特有的,这些字符在python和txt文档中是无法显示正常功能的,因此我们要进行替换操作,使用处理字符串字符串的replace方法,

new_content = content.replace('&nbsp;','').replace('<br/>','\n') #将网页中的换行符设置为pycharm的换行符

保存到本地

def write_file(file):
    with open ('盘龙.txt','a',encoding='gbk')as f: #编码方式应当根据网页的charset来决定
        f.write(file)
        f.close()

写入txt文件

        write_file(title) #写入每一章的标题
        write_file('\n') #换行
        write_file(new_content) #写入每一章的正文
        write_file('\n') #每一章与每一章之间加入换行符

最后做统一的处理与整合

import requests
import re
import json
from requests.exceptions import RequestException
def get_url(url):
    try:
        headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'}
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None
def parse_html(html):
    pattern = re.compile('.*?<dd><a href="(.*?)">(.*?)</a></dd>.*?',re.S)
    items = re.findall(pattern,html)
    for item in items:
        title = item[1]
        http = item[0]
        each_http = 'https://www.ddxs.cc%s'%http
        each_pattern = re.compile('<div id="content">(.*?)<div class="bottem2">.*?' ,re.S)
        content = str(re.findall(each_pattern,get_url(each_http)))
        new_content = content.replace('&nbsp;','').replace('<br/>','\n')
        write_file(title)
        write_file('\n')
        write_file(new_content)
        write_file('\n')
def write_file(file):
    with open ('盘龙.txt','a',encoding='gbk')as f: 
        f.write(file)
        f.close()
def main():
    url = 'https://www.ddxs.cc/ddxs/167986/'
    html = get_url(url)
    parse_html(html)
if __name__ == '__main__':
    main()
发布了1 篇原创文章 · 获赞 1 · 访问量 10

猜你喜欢

转载自blog.csdn.net/weixin_45830664/article/details/104975043