python爬取豆瓣书籍_python爬取豆瓣书籍排行

最近想通过爬取豆瓣数据来练习下爬虫,这次做一个爬取豆瓣书籍的信息。

需求:通过爬取豆瓣图书小说这一标签的数据,将数据存入csv或者数据库里面。

思路:先从网页上爬取数据,然后存到csv,然后读取csv的数据写到数据库中。(别问我为什么不直接写数据库,还要在csv中转一次。o(╯□╰)o。。。因为这个项目是逐渐练手的,是先写完csv,然后准备统计数据画图,所以想到还是存mysql好一点,就这样了。。。)

直接上个代码吧.。。。。。

画图表的方法还没完善,先上传上来,后面完善了再更

——————————————————————————————————————————————————

更新画图

# -*- coding: utf-8 -*-

'''

Created on 2018年8月17日

@author: zww

'''

import requests

import re

import random

import time

from lxml import etree

import pandas as pd

import matplotlib.pyplot as plt

import pymysql

from pymysql import charset

import csv

import codecs

# rating_list:评分, pl_list:评论人数

title_list, pub_list, rating_list, pl_list = [], [], [], []

def scrapy_contents(currentPage):

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'}

cookies = {

'cookies': '这里弄成自己的cookies'}

url = ''.join(['https://book.douban.com/tag/小说?start=',

str((currentPage + 1) * 20), '&type=T'])

res = requests.get(url, headers=headers, cookies=cookies)

res.encoding = "utf-8"

if (res.status_code == 200):

print('\n第{}页的数据爬取成功'.format(currentPage))

print(url)

else:

print('\n o(╯□╰)o第{}页的数据爬取失败'.format(currentPage))

print(url)

x = etree.HTML(res.text)

# 豆瓣每一页有20条数据

for i in range(1, 21):

title = x.xpath(

'//*[@id="subject_list"]/ul/li[{}]/div[2]/h2/a/@title'.format(i))

pub = x.xpath(

'//*[@id="subject_list"]/ul/li[{}]/div[2]/div[1]/text()'.format(i))

rating = x.xpath(

'//*[@id="subject_list"]/ul/li[{}]/div[2]/div[2]/span[2]/text()'.format(i))

pl = x.xpath(

'//*[@id="subject_list"]/ul/li[{}]/div[2]/div[2]/span[3]/text()'.format(i))

# 遇到有一页只有19条数据。。。。

try:

title_list.append(str(title[0]).strip())

pub_list.append(str(pub[0]).strip())

rating_list.append(str(rating[0]))

# 抓出来的数据是: (13376人评价),这里只取数字

num = re.findall(r"\d+", str(pl[0]))

pl_list.append(num[0])

except Exception as e:

print('第%d条记录获取数据失败' % i)

print(e)

continue

def draw_chart(name_list, num_list, title=u'评分比例'):

plt.bar(range(len(num_list)), num_list,

tick_label=name_list, facecolor='#ff9999', edgecolor='white', )

plt.title(title)

plt.savefig(u'图书评分的柱状图') # 保存

plt.show()

def draw_pie(name_list, num_list, title=u'评分比例'):

plt.title(title)

# 正圆

plt.axes(aspect='equal')

# patches, l_texts, p_texts,为了得到饼图的返回值,p_texts饼图内部文本的,l_texts饼图外label的文本

patches, l_text, p_text = plt.pie(

num_list, labels=name_list, autopct='%1.1f%%',

pctdistance=0.8, textprops={'fontsize': 6, 'color': 'k'}, radius=1)

plt.savefig(u'图书评分的饼图') # 保存

plt.show()

def save_file(filename):

infos = {'书名': title_list, '出版信息': pub_list,

'评分': rating_list, '评论人数': pl_list}

data = pd.DataFrame(

infos, columns=['书名', '出版信息', '评分', '评论人数'])

data.to_csv(filename, index=False)

def insert(cur, sql, args):

cur.execute(sql, args)

def get_conn(host, port, user, passwd, db):

conn = pymysql.connect(

host=host, port=port, user=user, passwd=passwd, db=db, charset='utf8')

return conn

def query(cur, sql):

cur.execute(sql)

result = cur.fetchall()

return result

def read_csv_to_mysql(filename):

with codecs.open(filename=filename, mode='r', encoding='utf-8') as f:

reader = csv.reader(f)

head = next(reader)

conn = get_conn(

'localhost', 3306, 'root', '123456', 'test_scrapy')

cur = conn.cursor()

sql = '''insert into novel(BookName,Pub,Score,CommentNum) values(%s,%s,%s,%s)'''

for item in reader:

args = tuple(item)

insert(cur, sql=sql, args=args)

conn.commit()

cur.close()

conn.close()

def Drawing(name_list, num_list):

plt.rcParams['figure.figsize'] = (12, 8) # 设置图片的大小1200*800

plt.rcParams['font.sans-serif'] = ['SimHei'] # 这两句是为了显示中文不乱码

plt.rcParams['font.family'] = 'sans-serif'

draw_chart(name_list, num_list)

# draw_pie(name_list, num_list)

def main(scrapyPage):

for i in range(1, scrapyPage + 1):

scrapy_contents(i)

# 随机等待时间,免得被封ip

time.sleep(round(random.uniform(1, 2), 2))

now = time.strftime('%Y-%m-%d %H-%M-%S', time.localtime())

filename = now + "豆瓣图书评分信息.csv"

save_file(filename)

print('scrapy done!')

# 写到mysql里面

read_csv_to_mysql(filename)

if __name__ == '__main__':

main(48)

conn = get_conn(

'localhost', 3306, 'root', '123456', 'test_scrapy')

cur = conn.cursor(pymysql.cursors.DictCursor) # 字典形式返回

cur_list = conn.cursor() # 元组形式返回

sql = '''SELECT DISTINCT(Score) from novel ORDER BY Score desc'''

Scores = query(cur_list, sql)

Scores_num = {}

for i in Scores:

sql = 'SELECT count(*) as c from novel where Score =%s' % i

num = query(cur, sql)

num_value = num[0]['c']

num_key = str(i[0])

Scores_num[num_key] = num_value

name_list = list(Scores_num.keys())

num_list = list(Scores_num.values())

cur.close()

cur_list.close()

conn.close()

Drawing(name_list, num_list)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值