下载豆瓣图片标为‘小说’下的所有基本信息并导出到CSV文件

爬虫背景
目的:下载豆瓣图片标为‘小说’下的所有基本信息并导出到CSV文件
复制前的url:https://book.douban.com/tag/小说?start=0&type=T
复制后的url:https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T
使用到的模块: 1、urllib.request 2、requests 3、BeautifulSoup 4、csv
分析过程:
1、使用urllib.request.quote解决中文到ASCII的编码问题
2、使用requests模块进行网页请求
3、使用BeautifulSoup解析网页内容
4、使用CSS删选器查找相应要爬取的内容。注:使用定位元素后右击COPY-COPY SELECTOR 直接复制定位代码(对小白来说神器啊!!!)
5、使用python自带csv模块导出文件(这个还不熟悉)
爬虫结果图:
在这里插入图片描述

代码如下:

# 爬取豆瓣读书各分类下的小说主要信息:['书名', '作者', '出版时间', '价格(元)', '评分', '评价人数']
import urllib.request
import requests
from bs4 import BeautifulSoup
import csv
# 使用python 内置模块csv生成导出csv文件

key = '小说'
# 豆瓣网上的标签,可根据需要进行添加
# 本案例仅爬取‘小说’类下的所有书籍信息,如需下载其他分类,代码需稍微修改一下
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}
book_names = []
author_list = []
time_list = []
price_list = []
urls = []
number = 49
pingjias = []
rating_nums = []

#获取总计number个网页的URL
def page_urls(key, number):
    # 使用urllib.request.quote进行中文到ASCII的编码
    key_ascii = urllib.request.quote(key)
    for i in range(number):
        url = 'https://book.douban.com/tag/' + str(key_ascii) + '?start=' + str(i * 20) + '&type=T'
        urls.append(url)
    return urls

# 获取每个页面的SOUP
def get_soup(url):
    html = requests.get(url, headers=headers).text
    soup = BeautifulSoup(html, 'html.parser')
    return soup

# 获取每个URL中的所有书名
def get_book_names(soup):
    for i in range(1, 21):
        book_name = soup.select("#subject_list > ul > li:nth-child(" + str(i) + ") > div.info > h2 > a")
        # 推荐使用for循环来进行书名查找。原因book_name[0]也可以,本来搜索结果就一个,但考虑每个网页的书籍不一定是20本
        # 本案例中就有页面中的书量不到20本,使用book_name[0]就会报错,使用for循环提取即使搜索为None也可继续执行
        # 下同!!!
        for book_name in book_name:
            book_name = ''.join(list(book_name.stripped_strings))
            book_names.append(book_name)
    return book_names

# 获取每个URL中的所有作者、价格、出版时间、评价分数、评价人数
def get_author_time_price_rating_pingjia(soup):
    for i in range(1, 21):
        author_time_price = soup.select("#subject_list > ul > li:nth-child(" + str(i) + ") > div.info > div.pub")
        for author_time_price in author_time_price:
            author_time_price = author_time_price.get_text().strip().split('/')
            author_list.append(author_time_price[0].split())
            if len(author_time_price) >= 4:
                time_list.append(author_time_price[-2])
                price_list.append(author_time_price[-1].strip('元'))
            else:
                time_list.append('null')
                price_list.append('null')

        rating_num = soup.select(
            '#subject_list > ul > li:nth-child(' + str(i) + ') > div.info > div.star.clearfix > span.rating_nums')
        for rating_num in rating_num:
            rating_num = rating_num.get_text().strip()
            rating_nums.append(rating_num)

        pingjia = soup.select(
            '#subject_list > ul > li:nth-child(' + str(i) + ') > div.info > div.star.clearfix > span.pl')
        for pingjia in pingjia:
            pingjia = pingjia.get_text().strip().lstrip('(').rstrip(')').strip('人评价')
            pingjias.append(pingjia)

    return (author_list, time_list, price_list, rating_nums, pingjias)


def main():
    urls = page_urls(key, number)
    for url in urls:
        soup = get_soup(url)
        book_names = get_book_names(soup)
        author_list, time_list, price_list, rating_nums, pingjias = get_author_time_price_rating_pingjia(soup)

    # 设置导出CSV文件的路径地址及名称
    file_path = r'C:\Users\Administrator\Desktop\liliang.csv'
    # 添加newline=''防止写入时写一行又插入一条空行
    with open(file_path, 'w', newline='', encoding='utf-8') as f:
        # 使用字典的方式写入CSV文件
        field_names = ['书名', '作者', '出版时间', '价格(元)', '评分', '评价人数']
        f_csv = csv.DictWriter(f, field_names)
        f_csv.writeheader()
        for i in range(len(author_list)):
            f_csv.writerow(
                {'书名': book_names[i],
                 '作者': author_list[i],
                 '出版时间': time_list[i],
                 '价格(元)': price_list[i],
                 '评分': rating_nums[i],
                 '评价人数': pingjias[i]
                 }
            )
if __name__ == '__main__':
    main()
发布了6 篇原创文章 · 获赞 0 · 访问量 88

猜你喜欢

转载自blog.csdn.net/lianglee513/article/details/105031380