首页 > 编程语言 >Python爬虫--爬取当当网关于python的书籍

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

时间:2023-06-06 22:25:01浏览次数:45  
标签:return 数据 Python excel db python items data 当当网

(一)选题背景

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

(二)步骤解释

使用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()

 

标签:return,数据,Python,excel,db,python,items,data,当当网
From: https://www.cnblogs.com/asdsdddhhhhtqwe/p/17461883.html

相关文章

  • python函数的位置参数和关键字参数
    基本类型:(1)位置参数(positional): 传参时不带"变量名=",顺序不可变, 需要按照函数定义时参数的顺序进行传参.(2)关键字参数(keyword):使用key=value形式传参, 传参时前面加上"变量名=",顺序可变,可以不按照函数定时参数的顺序进行传参.(3)可变位置参数(*args):......
  • python-日记模块模板
    1"""2logging配置3"""45#定义三种日志输出格式开始6standard_format='[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'\7'[%(levelname)s][%(message)s]......
  • 实验6 turtle绘图与python库应用编程体验
    实验任务1task1_1fromturtleimport*defmoveto(x,y):'''画笔移动到坐标(x,y)处'''penup()goto(x,y)pendown()defdraw(n,size=100):'''绘制边长为size的正n边形'''for......
  • python笔记
    python官方文档6.6的代码:frommaiximportcamera,mjpg,displayimportsocket#host_name='192.168.4.1'shuzu=bytearray(57600)#bytes是不能被修改的#s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#地址簇:AF_INET(IPv4)类型:SOCK_STREAM(使用TCP传输控......
  • python opencv GaussianBlur
    pythonopencvGaussianBlur importcv2#Loadtheimageimg=cv2.imread('20230222100736979.jpg')#ApplyaGaussianblurwithakernelsizeof5x5blur=cv2.GaussianBlur(img,(5,5),0)#Displaytheoriginalandblurredimagessidebysi......
  • Python正则表达式学习(5)——re.findall()
    re.findall(pattern,string,flags=0)返回字符串中模式的所有非重叠匹配,作为字符串列表。字符串从左到右扫描,并按照找到的顺序返回匹配项。如果模式中存在一个或多个组,则返回组的列表;如果模式有多个组,这将是一个元组的列表。结果中包含空匹配,除非他们触及另一个匹配的开始。In[1......
  • Python正则表达式学习(4)——re.match() 和 re.search()
    Python提供了基于正则表达式的两种不同的原始操作:re.match()仅在字符串的开头检查匹配,只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none。re.search()检查字符串中任何位置的匹配例如:In[2]:re.match("c","absdbdfskdvc")In[3]:re.search("c","a......
  • 基于《PythonCookbook》的学习(3)——利用 Shell 通配符做字符串匹配
    fnmatch模块提供了fnmatch()和fnmatchcase()两个函数可以使用通配符模式对文本进行匹配fnmatch所完成的匹配操作有点介乎于加单的字符串方法和全功能的正则表达式之间。感觉蛮鸡肋的…:(......
  • Python正则表达式学习(3)——re.compile()
    re.compile(pattern,flags=0)将正则表达式pattern编译为正则表达式对象,可用于使用其match()和search()方法进行匹配。顺序:prog=re.compile(pattern)result=prog.match(string)等价于:result=re.match(pattern,string)但是当单个程序中的表达式被多次使用时,使用re.comp......
  • 基于《PythonCookbook》的学习(1)——针对任意多的分隔符拆分字符串
    问题:需要将字符串拆分为不同的字段,但是分隔符(以及分隔符之间的空格)在整个字符串中并不一致re.split()方法比str.split()方法更为灵活,可以为分隔符指定多个模式re.split()方法返回一个list目标字符串:In[15]:lineOut[15]:'asdasdsadas,,,,sdfdsfi///ds...ds/essd//s......