Python爬虫--爬取当当网关于python的书籍

发布时间 2023-06-06 22:10:03作者: 叉烧仙草蜜

(一)选题背景

  因为现如今的科技越来越发达,人们对于信息的获取道路变得更加宽广了,在以前的话,人们会受到空间,时间,科技等问题的阻碍,对于大部分知识只有在书籍当中才能够找到。不过随着现如今科技的进步,信息的载体也会变得越来越多,信息的传播方式也变得多种多样,电子书就可以通过图像、声音、文字来传播你想要的知识。还有就是电子书的传播形式更加便于人们去理解文字的意思,电子书可以通过图像、声音、文字来传播你所想要的东西,这对于单纯的书本上的文字来说,效果是要更好的。并且电子书上可以找到许多书籍,不用你自己去书店买就能够看到你想看的书,这也让人们的生活变得更加方便。

(二)步骤解释

使用requests模块

请求地址

获取响应数据

解析响应数据

把解析的数据保存到mysql数据库或者excel

爬取网址:http://search.dangdang.com/

(三)具体步骤

1、发起请求获取响应截图

 2、解析数据截图

 3、创建数据库截图

4、创建数据表截图

 5、保存数据到数据库截图

6、 保存所有数据到列表截图

 7、保存数据到excel截图

 8、制作柱状图截图

 

 9、爬取内容保存在excel截图

 (三)完整代码

import numpy as np
import pandas as pd
import pymysql
import requests
from lxml import etree
import matplotlib.pyplot as plt


# 爬取书籍关键字
key = "python"
# 初始url,用于拼接列表页url
source_url = 'http://search.dangdang.com/'


def scrape_api(page):
"""
请求当当网,获取响应
:return:
"""
# 构造请求地址
start_url = f'{source_url}?key={key}&page_index={page}&sort_type=sort_sale_amt_desc#J_tab'
print(f"爬取第{page}页,该页url是:{start_url}")
# 请求地址,获取响应
response = requests.get(start_url)
# 获取响应
data = response.text
# 将响应的数据返回
return data


def parse_data(data):
"""
解析请求当当网的数据
:return:
"""
# 所有数据保存到列表
items = []
# 解析响应数据
selector = etree.HTML(data)
# 拿到列表页所有书籍
lis = selector.xpath('//div[@class="con shoplist"]//li')
# 遍历列表页所有书籍,取出每一本书籍的信息
for li in lis:
# 书名
title = li.xpath('./a/@title')[0]
# 价格
price = li.xpath('.//p[contains(@class, "price")]/span[1]/text()')[0]
# 作者
author = li.xpath('.//a[@dd_name="单品作者"]/@title')
if author:
author = author[0]
else:
author = ""
# 出版时间
date = li.xpath('./p[@class="search_book_author"]/span[2]/text()')
if date:
date = date[0]
date = str(date).strip(' /')
else:
date = ""
# 出版社
publisher = li.xpath('.//a[@dd_name="单品出版社"]/@title')[0]
# 书籍简介
detail = li.xpath('./p[@class="detail"]/text()')
# detail有时没有,结果None
if detail:
detail = detail[0]
else:
detail = ""

# 构造字典保存数据
item = {
'title': title,
'author': author,
'date': date,
'publisher': publisher,
'price': price,
'detail': detail
}
# 将数据添加到列表中
items.append(item)

# 将数据列表返回
return items


def create_database():
"""
创建数据库
:return:
"""
# 连接数据库,password:自己的数据库密码
db = pymysql.connect(host='localhost', user='root', password='123456', port=3306)
# 创建名为mydb的数据库
cursor = db.cursor()
cursor.execute("CREATE DATABASE IF NOT EXISTS mydb DEFAULT CHARACTER SET utf8mb4")
db.close()


def create_table():
"""
创建数据表
:return:
"""
# 连接数据库,password:自己的数据库密码
db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='mydb')
cursor = db.cursor()
# 创建表tb_books
sql = 'create table IF NOT EXISTS tb_books (title varchar(521), author varchar(256), ' \
'publisher varchar(255), date varchar(255), price varchar(255), detail TEXT)'
cursor.execute(sql)
db.close()


def save_data(item):
"""
保存数据到数据库
:param data: 每一条书籍信息
:return:
"""
# 连接数据库
db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='mydb')
cursor = db.cursor()
table = 'tb_books'
# 取出保存在字典内的字段,进行sql语句拼接
keys = ', '.join(item.keys())
values = ', '.join(['%s'] * len(item))
sql = 'INSERT INTO {table}({keys}) VALUES ({values})'.format(table=table, keys=keys, values=values)
try:
if cursor.execute(sql, tuple(item.values())):
print("数据插入成功")
db.commit()
except Exception as e:
print(e)
print("数据插入失败")
db.rollback()

db.close()


def save_excel(file_name, data):
"""
保存数据
:param file_name: excel文件名字
:param data: 所有书本的信息
:return:
"""
df = pd.DataFrame(data)
df.to_excel(file_name, index=False)
print("数据写入成功!!")


def produce_bar():
"""
制作出版社统计数据柱状图
:return:
"""
# 读取Excel文件
df = pd.read_excel('当当网python书籍数据.xlsx')

# 统计每个出版社的个数
publisher_counts = df['出版社'].value_counts()

# 设置字体和编码格式
plt.rcParams['font.sans-serif'] = 'simhei'
plt.rcParams['axes.unicode_minus'] = False

# 创建颜色映射
cmap = plt.get_cmap('tab20') # 使用tab20颜色映射,可以根据需求选择其他颜色映射

# 绘制柱状图
plt.bar(publisher_counts.index, publisher_counts.values, color=cmap(np.arange(len(publisher_counts))))

# 设置横纵坐标标签
plt.xlabel('出版社')
plt.ylabel('出版社个数')

# 标题
plt.title('出版社统计')

# 自动调整横坐标标签旋转角度,以避免重叠
plt.xticks(rotation=90, fontsize=9)

# 显示图形
plt.show()


# 保存excel数据列表
items = [[] for x in range(6)]


def main():
"""
程序运行主函数
:return:
"""
# 创建数据库
create_database()
# 创建表
create_table()
# 构造页数,进行url拼接
for page in range(1, 6):
# 请求网址,获取响应
data = scrape_api(page)
# 解析响应数据
datas = parse_data(data)
# 遍历书籍数据列表,取出每条书籍数据
for data in datas:
# 保存数据到数据库
# save_data(data)
# 取出每条数据的value值
data_list = [value for value in data.values()]
# 将value值加入到itmes列表,便于excel保存
for i in range(6):
items[i].append(data_list[i])

# 取出items每一个索引值内的数据,与excel列名一一对应
excel_data = {
'书名': items[0],
'作者': items[1],
'出版时间': items[2],
'出版社': items[3],
'价格': items[4],
'书籍简介': items[5]
}

# 保存数据到excel
save_excel('当当网python书籍数据.xlsx', excel_data)


if __name__ == '__main__':
# 执行主函数
# main()
# 制作柱状图
produce_bar()