基于爬虫和Kettle的书籍信息采集与预处理

news2024/9/30 13:07:57

一:爬虫

1、爬取的目标

将读书网上的书籍的基本信息,比如:封面、书名、作者、出版社、价格、出版时间、内容简介、作者简介、书籍目录、ISBN和标签爬取出来,并将爬取的结果放入数据库中,方便存储。

2、网站结构

   

图1读书网书籍类别详情

此次实验爬取读书网页面中文学、小说、传记、青春文学、艺术、散文随笔、励志、人文社科、经济管理、励志十大类书籍。

每一类书籍包括书名、价格、作者、出版社、ISDN、出版时间、封面以及书籍简介、作者简介、书目录和书籍所属类别。页面具体情况如图2所示。

图2读书网书籍属性设计详情

3、爬虫技术方案

1)、所用技术:

         网站解析的使用的是Xpath、数据库存储使用的是pymysql。

2)、爬取步骤:

    (1)、分析目标网站:了解页面结构;

(2)、获取页面内容:使用python中的requests库来获取页面内容;

(3)、定位页面:使用Xpath定位我们所需要的数据的位置;

(4)、连接数据库:创建数据连接,放入自己数据库的端口、用户和密码等数据,使得连接上自己的数据库,将爬取好的数据返给数据库中,方便存储;

(5)、关闭连接:关闭数据库连接。

4、爬取过程:

   

1)、常量定义

    

此处定义了网页后缀END=‘.html’用于进行网页拼接。

Start_Page = 1 定义爬取起始页码,end_Page = 10 定义爬取结束页码。

Base_url 用于设置爬取网页的基础网站,进行后续网页拼接。

Book_type={},该字典设置爬取书籍类别。

Header={},该字典进行请求头设置。

2)、设置游标,连接数据库,再使用for循环,确保书籍能够循环爬取,最后将爬取完毕的数据放入数据库中,最后关闭数据库的连接。

  

   3)、一级链接爬取,接收参数基本网页地址、书籍类型、网页页数后,再使用requests库中r.get(url=url,headers=header)发送请求,使用response接收请求数据。

   

4)、二级链接爬取,在数据获取步骤,进行更细致的xpath语句书写。

使用try-except语句提高程序健壮性,返回一个书籍信息字典。

      

      5)、保存数据,创建游标,编写sql语言,之后执行sql语言,执行成功就插入所给的表,如果执行失败则输出插入失败。

      

5、爬虫结果

预处理

  1. 删除列

1)、新建转换,之后使用表输入,将MySQL文件中的表输入kettle。需要连接数据库的类型是MySQL,主机名称是localhost、用户是root、密码是root、端口号是3306。

    

之后进行字段获取。

2)、选择转换中的字段选择进行列删除,将dictroy这个列进行删除。

2、选择转换中的增加常量,增加remainder这一列,查询书籍卖出剩余的情况。

    

  1. 、最后选择文本文件输出,将处理好的数据输出,输出的格式是csv文件,分割符用逗号隔开,编码用UTF-8J进行转码,防止输出文件中有乱码。文本文件命名为姓名_处理完成_csv。

4、预处理完全处理全流程

三、爬虫源代码

import re
import requests
from lxml import etree
import pymysql
import datetime
"""
爬取一个网站
1.获得数据不小于一千条
2.每条数据属性不小于10
"""

END = '.html'
start_Page = 1
end_Page = 10
base_url = 'https://www.dushu.com'
# 以字典形式保存每一类对应的网页数字
book_type = {"文学": 1077, "小说": 1078, "传记": 1081, "青春文学": 1079,
     "艺术": 1082, "散文随笔": 1163, "鉴赏": 1222, "人文社科": 1003,
     "经济管理": 1004, "励志": 1094
}

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

def get_one_bookInfo_link(base_url, _type, page):
    # url 控制爬取的书籍类型、网页页数
    url = base_url+'/book/'+str(_type)+'_'+str(page)+END
    # print(url)
    response = requests.get(url=url, headers=header)
    if response.status_code == 200:
        htmlTEXT = response.content.decode(response.apparent_encoding)
        html = etree.HTML(htmlTEXT)
        bookLinke_List = html.xpath('//div[@class="container margin-top"]//div[@class="bookslist"]/ul/li/div[@class="book-info"]/h3/a/@href')
        return bookLinke_List
    else:
        print("请求失败")


def get_oneBook_info(bookLinke):
    url = base_url + bookLinke
    content = requests.get(url=url, headers=header)
    if content.status_code == 200:
        info = etree.HTML(content.content.decode(content.apparent_encoding))
        # 获取书籍详细信息,十个
        try:
            img = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-pic"]//img/@src')[0]  # 封面
            title = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-pic"]//img/@alt')[0]  # 书名
            author = info.xpath('//div[@id="ctl00_c1_bookleft"]/table//tr[1]//td[2]/text()')[0]  # 作者
            publish = info.xpath('//div[@id="ctl00_c1_bookleft"]/table//tr[2]//td[2]/text()')[0]  # 出版社
            temp_price = info.xpath('//div[@id="ctl00_c1_bookleft"]/p/span/text()')[0]  # 价格
            price = temp_price.split('¥')[1]
            time = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-details"]/table//tr[1]/td[@class="rt"][2]/text()')[0]  # 出版时间
            cont = info.xpath('//div[@class="container margin-top"]//div[contains(@class, "book-summary")][1]/div/div/text()')[0]   # 内容简介
            blurb = info.xpath('//div[@class="container margin-top"]//div[contains(@class, "book-summary")][2]/div/div/text()')[0]  # 作者简介
            directory = info.xpath('//div[@class="container margin-top"]//div[contains(@class, "book-summary")][3]/div/div/text()')[0]  # 书籍目录
            isbn = info.xpath('//div[@class="bookdetails-left"]/div[@class="book-details"]/table//tr[1]/td[@class="rt"][1]/text()')[0]   # ISBN
            label = info.xpath('//div[@id="ctl00_c1_bookleft"]/table//tr[4]//td[2]/text()')[0]  # 标签
            # 使用字典保存一本书籍的信息
            book_info = {
                "img": img,
                "title": title,
                "author": author,
                "publish": publish,
                "price": price,
                "time": time,
                "cont": cont,
                "blurb": blurb,
                "directory": directory,
                "isbn": isbn,
                "label": label
            }
            return book_info
        except Exception as e:
            print("爬取时单本书籍获取出现错误:", e, "\n发生错误地址为:"+url)
            err_info = {
                "img": 'https://a.dushu.com/img/n200.png',
                "title": 'titleEro',
                "author": 'authorEro',
                "publish": 'publishEro',
                "price": '00.00',
                "time": '2001-01-01',
                "cont": 'contEro',
                "blurb": 'blurbEro',
                "directory": 'directoryEro',
                "isbn": 'isbnEro',
                "label": 'labelEro'
            }
            return err_info
    else:
        print("请求失败")


def set_BookInfo_ToMySql(book_info, db):
    # print(book_info.values())
    cursor = db.cursor()
    # sql语句
    sql = "INSERT INTO book(img,title,author,publish,price,time,cont,blurb,directory,isbn,label) VALUES " \
          "('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')"\
          %(book_info["img"], book_info["title"], book_info["author"], book_info["publish"],
            book_info["price"], book_info["time"], book_info["cont"], book_info["blurb"],
            book_info["directory"], book_info["isbn"], book_info["label"])
    print(book_info.values())
    try:
        # 执行sql语句
        if cursor.execute(sql):
            print('插入数据成功')
            # 提交到数据库执行
            db.commit()  # 持久化
    except Exception as e:
        # 如果发生错误则回滚
        print("插入失败", e)
        db.rollback()


def main():
    #  用于存储计算数据爬取数量
    count = 0
    # 连接数据库
    db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='pachong')
    # 开启爬取程序
    for type in book_type:  # 控制爬取书籍的类别
        for i in range(start_Page, end_Page+1):    # 控制每一类爬取的页数
            # 每一个网页的书籍的二级连接
            bookLinke_List = get_one_bookInfo_link(base_url=base_url, _type=book_type[type], page=i)
            if bookLinke_List:
                for link in bookLinke_List:
                    print(link)
                    info = get_oneBook_info(link)
                    info['label'] = type
                    # print(info)
                    set_BookInfo_ToMySql(book_info=info, db=db)
                    count += 1
            else:
                print("爬取内容为空")
    # 数据插入完成后关闭数据库
    if db:
        db.close()
        print("关闭数据库成功,程序结束")
    else:
        print("数据加载成功,数据库未关闭")
    return count


if __name__ == '__main__':
    print("Run...")
    # 获取开始时间
    start_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    # db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='movie')
    # info = get_oneBook_info('/book/13981332/')
    # set_BookInfo_ToMySql(info, db=db)
    # db.close()
    print("已爬取书籍数量:", main())
    # 获取结束时间
    end_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print("程序结束{}\n运行开始时间:{}".format(end_time, start_time))

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1378478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HackTheBox - Medium - Linux - UpDown

UpDown UpDown 是一台中等难度的 Linux 机器,暴露了 SSH 和 Apache 服务器。在Apache服务器上,有一个Web应用程序,允许用户检查网页是否已启动。服务器上标识了一个名为“.git”的目录,可以下载以显示目标上运行的“dev”子域的源…

从事铁路工作保护足部,穿什么劳保鞋更安全

铁路运输在我国交通运输业中起着骨干作用,为国民经济的可持续发展和人口流动做出了巨大贡献。安全是铁路运输不可忽视的问题,在作业场地随处能见到“安全就是生命,责任重于泰山”的安全标语,由此可见安全问题是放在首位的。 铁路施…

❤ Vue3 完整项目太白搭建 Vue3+Pinia+Vant3/ElementPlus+typerscript(一)yarn 版本控制 ltb (太白)

❤ 项目搭建 一、项目信息 Vue3 完整项目搭建 Vue3PiniaVant3/ElementPlustyperscript&#xff08;一&#xff09;yarn 版本控制 项目地址&#xff1a; 二、项目搭建 &#xff08;1&#xff09;创建项目 yarn create vite <ProjectName> --template vueyarn install …

用我这套模板,几分钟做出文档网站!

大家好&#xff0c;我是保姆皮&#xff0c;最近我上线了自己的《编程宝典》网站&#xff0c;可以在线阅读我分享过的各种编程学习路线和知识干货。 指路&#xff1a;https://codefather.cn/ 不少小伙伴催我出教程&#xff0c;说也想做个类似的文档网站。 所以我用最快的速度出了…

挑选富集分析结果 enrichments

#2.2挑选term---selected_clusterenrichenrichmets[grepl(pattern "cilium|matrix|excular|BMP|inflamm|development|muscle|vaso|pulmonary|alveoli",x enrichmets$Description),]head(selected_clusterenrich) distinct(selected_clusterenrich)# remove duplica…

firewalld防火墙命令行工具

firewall-cmd命令 &#xff08;1&#xff09;启动、停止、查看firewalld服务 在安装CentOS 7系统时&#xff0c;会自动安装firewalld 和图形化工具firewall-config.执行以下命令可 以启动 firewalld 并设置为开机自启动状态。 [rootllcgc ~]# systemctl start firewalld.serv…

关于Python里xlwings库对Excel表格的操作(三十一)

这篇小笔记主要记录如何【如何使用“Chart类”、“Api类"和“Axes函数”设置绘图区外框线型、颜色、粗细及填充颜色】。前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】 &#xff08;1&#xff09;如何安…

Unity中URP下实现能量罩(扭曲流光花纹)

文章目录 前言一、能量罩花纹1、在属性面板接收能量罩花纹纹理2、申明 纹理 和 采样器3、在顶点着色器,应用 Tilling 和 Offset4、在片元着色器,纹理采样后,与之前的结果相乘输出二、能量罩流光1、在顶点着色器,记录原uv值2、在片元着色器,使用 uv 的 y 值,乘以一个系数 …

Linux的DNS域名解析服务

一.DNS基础 1.1 DNS简介 DNS域名系统 &#xff08;Domain Name System 缩写为&#xff1a;DNS&#xff09;是因特网的一项核心服务&#xff0c;它作为可以将 域名 和 IP地址 相互映射的一个分布式数据库&#xff0c;能够使人更加方便的访问互联网&#xff0c;而不用去记住能够…

企业数据中台整体介绍及建设方案:文件全文51页,附下载

关键词&#xff1a;数据中台解决方案&#xff0c;数据治理&#xff0c;数据中台技术架构&#xff0c;数据中台建设内容&#xff0c;数据中台核心价值 一、什么是数据中台&#xff1f; 数据中台是指通过数据技术&#xff0c;对海量数据进行采集、计算、存储、加工&#xff0c;…

DNS域名解析以及操作流程

dns:将域名转化为IP地址的过程&#xff0c;域名方便人们记忆&#xff0c;ip地址过长&#xff0c;且都是数字&#xff0c;不方便记忆&#xff0c;所以才出现了域名。 怎么实现访问域名等于访问ip地址 1.老方法&#xff1a;写入文件里 /etc/hosts 左边 IP地址 右边域名 格式例…

XSS的利用(包含:蓝莲花、beef-xss)

0x00、环境搭建 dvwa靶场 操作指南和最佳实践:使用 DVWA 了解如何防止网站漏洞_dvwa源代码-CSDN博客 xss漏洞接收平台 下载:GitHub - firesunCN/BlueLotus_XSSReceiver 将解压后的BlueLotus_XSSReceiver原代码放置 phpstudy 安装目录的WWW文件夹下 访问平台:http://127…

N-137基于springboot,vue运动会报名管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueAvueElementUI 服务端技术&#xff1a;springbootmybatis 本项…

XCTF:MISCall[WriteUP]

使用file命令&#xff0c;查看该文件类型 file d02f31b893164d56b7a8e5edb47d9be5 文件类型&#xff1a;bzip2 使用bzip2命令可对该文件进行解压 bzip2 -d d02f31b893164d56b7a8e5edb47d9be5 生成了一个后缀为.out的文件 再次使用file命令&#xff0c;查看该文件类型 file…

WARNING: IPv4 forwarding is disabled. Networking will not work.

今天用docker部署容器&#xff0c;发现一个问题&#xff0c;docker-compose up启动成功&#xff0c;但无法正常访问接口。 查找问题步骤&#xff1a; 1、直接在服务器运行jar包&#xff0c;发现可以正常启动&#xff0c;也能正常访问接口&#xff0c;排除jar包本身问题以及防…

Google推出Telecom Jetpack库,让Android通话应用创建更简单

Google推出Telecom Jetpack库&#xff0c;让Android通话应用创建更简单 Telecom Jetpack库的最新Alpha版本已经推出。该库提供了多个API&#xff0c;以简化Android开发者创建语音和/或视频通话应用程序的过程&#xff0c;支持常见功能&#xff0c;例如接听/拒绝、音频路由等等…

在机械行业中,直线导轨和弧形导轨哪个应用范围更广泛?

弧形导轨和直线导轨是两种常见的导轨类型&#xff0c;直线导轨主要被用于高精度或快速直线往复运动场所&#xff0c;而弧形导轨是一种专门设计用于曲线运动的导轨系统&#xff0c;那么在机械行业中&#xff0c;直线导轨和弧形导轨哪个应用范围更加广泛呢&#xff1f; 直线导轨主…

python如何安装numpy

1. 根据python版本下载相应版本的numpy保存至D:\Program Files (x86)\Python\Python37\Scripts\ numpy下载地址 2. winR&#xff0c;输入cmd&#xff0c;打开命令行窗口&#xff0c;定位到python的安装目录 3. 输入python -m pip install numpy或定位到目录&#xff1a;D:\P…

【STC8A8K64D4开发板】第2-9讲:比较器

学习目的学习比较器的作用和原理。掌握比较器的应用流程包括配置、启动以及中断服务函数的编写。 比较器原理 STC8A8K64D4单片机片内集成了比较器&#xff08;Comparator&#xff09;&#xff0c;比较器有两个输入端IN&#xff08;正端输入端&#xff09;和&#xff08;负端输…

代码随想录算法训练营第25天 | 216.组合总和III 17.电话号码的字母组合

目录 216.组合总和III &#x1f4a1;解题思路 回溯三部曲 &#x1f4bb;实现代码 17.电话号码的字母组合 &#x1f4a1;解题思路 # 数字和字母如何映射 # 回溯法来解决n个for循环的问题 &#x1f4bb;实现代码 216.组合总和III 题目链接&#xff1a;216.组合总和III …