首页 > 其他分享 >scrapy爬取当当网

scrapy爬取当当网

时间:2024-11-13 09:16:11浏览次数:3  
标签:获取 text price 当当网 爬取 item scrapy found self

网址:青春爱情文学_畅销青春爱情文学类图书【推荐 正版 价格】_青春文学-当当网

dangdang.py

import scrapy
from..items import DangdangBookItem

# 定义名为DangdangSpider的爬虫类,继承自scrapy.Spider类
class DangdangSpider(scrapy.Spider):
    # 爬虫的名称,用于在Scrapy项目中唯一标识这个爬虫
    name = "dangdang"
    # 当当网图书分类页面的基础URL,这里指向了某个图书分类页面(具体分类由URL中的参数决定)
    base_url = "https://category.dangdang.com/cp01.01.02.00.00.00.html"
    # 起始URL列表,爬虫开始抓取的页面,这里只设置了基础URL作为起始页面
    start_urls = [base_url]
    # 用于记录当前正在抓取的页码,初始化为1
    page_num = 1

    def parse(self, response):
        """
        解析函数,用于处理抓取到的页面内容(response),提取图书相关信息,并生成数据项(item),
        同时处理翻页逻辑,继续抓取后续页面内容。

        参数:
            response: 抓取到的页面响应对象,包含了页面的HTML内容等信息。
        """
        # 使用CSS选择器选取页面中包含图书信息的每个li元素(每个li通常对应一本书的信息展示块)
        books = response.css('ul.bigimg li')
        for book in books:
            item = DangdangBookItem()
            # 使用CSS选择器选取图书标题对应的元素(a标签)
            title_element = book.css('p.name a')
            # 进一步获取标题文本内容,如果获取到则去除两端空白字符后赋值给item['title'],
            # 如果没获取到则设置默认值 "Title not found"
            title = title_element.css('::text').get()
            if title:
                item['title'] = title.strip()
            else:
                item['title'] = "Title not found"

            # 使用CSS选择器选取图书当前价格对应的元素,并获取文本内容,
            # 如果获取到则去除价格符号'¥'和两端空白字符后赋值给item['price'],
            # 如果没获取到则设置默认值 "Price not found"
            price_text = book.css('span.search_now_price::text').get()
            if price_text:
                item['price'] = price_text.replace('¥', '').strip()
            else:
                item['price'] = "Price not found"

            # 使用CSS选择器选取图书原价对应的元素,并获取文本内容,
            # 如果获取到则去除价格符号'¥'和两端空白字符后赋值给item['original_price'],
            # 如果没获取到则设置默认值 "Original price not found"
            original_price_text = book.css('span.search_pre_price::text').get()
            if original_price_text:
                item['original_price'] = original_price_text.replace('¥', '').strip()
            else:
                item['original_price'] = "Original price not found"

            # 使用CSS选择器选取图书折扣对应的元素,并获取文本内容,
            # 如果获取到则通过字符串处理提取折扣数值(去除括号等多余字符)后赋值给item['discount'],
            # 如果没获取到则设置默认值 "Discount not found"
            discount_text = book.css('span.search_discount::text').get()
            if discount_text:
                item['discount'] = discount_text.split('(')[1].split(')')[0].strip()
            else:
                item['discount'] = "Discount not found"

            # 使用CSS选择器选取图书作者对应的元素(a标签),获取所有作者文本内容列表,
            # 如果获取到则用逗号连接作者名字并去除两端空白字符后赋值给item['author'],
            # 如果没获取到则设置默认值 "Author not found"
            authors = book.css('p.search_book_author a:first-child::text').getall()
            if authors:
                item['author'] = ', '.join(authors).strip()
            else:
                item['author'] = "Author not found"

            # 使用CSS选择器选取图书出版社对应的元素(a标签),获取出版社文本内容,
            # 如果获取到则去除两端空白字符后赋值给item['publisher'],
            # 如果没获取到则设置默认值 "Publisher not found"
            publisher = book.css('p.search_book_author a:last-child::text').get()
            if publisher:
                item['publisher'] = publisher.strip()
            else:
                item['publisher'] = "Publisher not found"

            # 使用CSS选择器选取图书评论数量对应的元素(a标签),获取文本内容,
            # 如果获取到则去除"条评论"字样和两端空白字符后赋值给item['comment_num'],
            # 如果没获取到则设置默认值 "Comment number not found"
            comment_num_element = book.css('p.search_star_line a')
            comment_num = comment_num_element.css('::text').get()
            if comment_num:
                item['comment_num'] = comment_num.replace('条评论', '').strip()
            else:
                item['comment_num'] = "Comment number not found"

            # 使用CSS选择器选取图书描述对应的元素(p.detail),获取所有描述文本内容列表,
            # 如果获取到则合并文本内容并去除两端空白字符后赋值给item['description'],
            # 如果没获取到则设置默认值 "Description not found"
            description_element = book.css('p.detail')
            description = description_element.css('::text').getall()
            if description:
                item['description'] = ' '.join([desc.strip() for desc in description]).strip()
            else:
                item['description'] = "Description not found"

            # 使用CSS选择器选取图书出版日期对应的元素(span元素),获取文本内容,
            # 如果获取到则去除两端空白字符后赋值给item['release_date'],
            # 如果没获取到则设置默认值 "Release date not found"
            release_date_element = book.css('p.search_book_author span:nth-child(2)::text').get()
            if release_date_element:
                item['release_date'] = release_date_element.strip()
            else:
                item['release_date'] = "Release date not found"

            # 将提取好信息的item(数据项)通过生成器返回,交给后续的管道(pipeline)处理
            yield item

        # 初始化下一页的URL为None
        next_page_url = None
        # 使用CSS选择器选取页面中指向“下一页”的链接元素(a标签)
        next_page_links = response.css('div.paging li.next a')
        if next_page_links:
            # 如果存在“下一页”链接,则获取第一个链接的href属性值作为下一页的URL
            next_page_url = next_page_links[0].attrib['href']
        if next_page_url:
            # 如果获取到了下一页的URL,则构造一个新的Scrapy请求,使用当前的解析函数(self.parse)
            # 作为回调函数继续处理下一页的内容,这样可以实现自动翻页抓取
            yield scrapy.Request(response.urljoin(next_page_url), callback=self.parse)
pipelines.py
import csv
from scrapy.exceptions import DropItem

# 定义名为DangdangBooksPipeline的管道类,用于处理爬虫提取到的数据项(item),
# 这里主要功能是将图书信息写入CSV文件。
class DangdangBooksPipeline:
    def open_spider(self, spider):
        """
        在爬虫启动时被调用,用于初始化文件相关操作,比如打开文件、决定写入模式(追加或覆盖),
        以及初始化CSV写入器等。

        参数:
            spider: 当前正在运行的爬虫对象实例。
        """
        try:
            # 尝试以读模式打开名为'dangdang_books.csv'的文件(用于检查文件是否已存在)
            with open('dangdang_books.csv', 'r', newline='', encoding='utf-8') as f:
                # 提示用户输入,决定是否追加数据到已存在的文件中
                choice = input("文件已存在,是否追加数据?(y/n): ")
                if choice.lower() == 'y':
                    # 如果用户选择追加(输入'y'),则以追加模式打开文件,并初始化CSV写入器,
                    # 指定写入的字段名(列名)
                    self.file = open('dangdang_books.csv', 'a', newline='', encoding='utf-8')
                    self.writer = csv.DictWriter(self.file, fieldnames=['书名', '价格', '原价',
                                                                        '折扣', '作者', '出版社',
                                                                        '评论数量', '描述', '出版日期'])
                else:
                    # 如果用户选择不追加(输入其他字符),则以覆盖写入模式打开文件,
                    # 并初始化CSV写入器,同时写入表头(字段名)
                    self.file = open('dangdang_books.csv', 'w', newline='', encoding='utf-8')
                    self.writer = csv.DictWriter(self.file, fieldnames=['书名', '价格', '原价',
                                                                        '折扣', '作者', '出版社',
                                                                        '评论数量', '描述', '出版日期'])
                    self.writer.writeheader()
        except FileNotFoundError:
            # 如果文件不存在,则以写入模式打开文件(相当于新建文件),
            # 初始化CSV写入器并写入表头(字段名)
            self.file = open('dangdang_books.csv', 'w', newline='', encoding='utf-8')
            self.writer = csv.DictWriter(self.file, fieldnames=['书名', '价格', '原价',
                                                                '折扣', '作者', '出版社',
                                                                '评论数量', '描述', '出版日期'])
            self.writer.writeheader()

    def process_item(self, item, spider):
        """
        处理每个数据项(item)的方法,在这里会对数据项进行验证,
        如果各项关键信息都存在,则进行格式转换后写入CSV文件,并返回该数据项让后续管道继续处理,
        如果有关键信息缺失,则丢弃该数据项。

        参数:
            item: 爬虫提取到的一个数据项,包含图书的各项信息。
            spider: 当前正在运行的爬虫对象实例。
        """
        # 检查数据项中各项关键信息是否都存在(不为空)
        if item['title'] and item['price'] and item['original_price'] and item['discount'] and item['author'] and item[
            'publisher'] and item['comment_num'] and item['description'] and item['release_date']:
            # 如果各项关键信息都存在,则构造一个新的字典,将英文键名转换为中文键名(对应CSV的列名)
            new_item = {
                '书名': item['title'],
                '价格': item['price'],
                '原价': item['original_price'],
                '折扣': item['discount'],
                '作者': item['author'],
                '出版社': item['publisher'],
                '评论数量': item['comment_num'],
                '描述': item['description'],
                '出版日期': item['release_date']
            }
            # 使用CSV写入器将转换后的字典数据写入CSV文件
            self.writer.writerow(new_item)
            return item
        else:
            # 如果有关键信息缺失,则抛出DropItem异常,表示丢弃这个无效的数据项
            raise DropItem(f"Invalid item: {item}")

    def close_spider(self, spider):
        """
        在爬虫关闭时被调用,用于关闭之前打开的文件资源。

        参数:
            spider: 当前正在运行的爬虫对象实例。
        """
        self.file.close()

返回结果

标签:获取,text,price,当当网,爬取,item,scrapy,found,self
From: https://blog.csdn.net/qq_68809241/article/details/143597483

相关文章

  • scrapy爬取桌面壁纸
    【桌面壁纸】电脑桌面壁纸图片大全_高清壁纸背景图-ZOL桌面壁纸importosimportscrapyfromfake_useragentimportUserAgentclassZolMeinvSpider(scrapy.Spider):name='zol_meinv'base_url='https://desk.zol.com.cn'start_url=base_url+'/mein......
  • Python爬虫实战案例(爬取图片)
    爬取图片的信息爬取图片与爬取文本内容相似,只是需要加上图片的url,并且在查找图片位置的时候需要带上图片的属性。这里选取了一个4K高清的壁纸网站(彼岸壁纸https://pic.netbian.com)进行爬取。具体步骤如下:第一步依然是进入这个页面,这个壁纸网站分为好几种类型的壁纸图片,......
  • 使用python爬取百度热搜
    文章目录前言一、requests是什么?二、使用步骤1.引入库2.获取页面数据3.使用xpath解析页面,获取词条列表信息4.获取指定元素信息,添加到dataframe中5.保存数据到指定的文件或数据库总结前言本文介绍使用request获取百度热搜的简单功能一、requests是什么?Pythonreq......
  • 爬取b站番剧数据
    这就是b站番剧页面,然后f12进入开发者模式找出url再观察第二页的url和第一页有何区别,发现page=页数,可以通过这个实现翻页,有不懂的欢迎来问,一起交流,新人感谢支持,也欢迎给出优化方案参考代码:importrequestsimportjsonimportpymongomongo_conn=pymongo.MongoClient(......
  • Python图片链接爬虫爬取图片代码
    importrequestsurl=‘https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/05/0F/ChMkJ1erCYqIQptxAAPESMfBQZoAAUU6QB4oVwAA8Rg091.jpg’headers={‘user-agent’:‘Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/1......
  • 在Scrapy爬虫中应用Crawlera进行反爬虫策略
    在互联网时代,数据成为了企业竞争的关键资源。然而,许多网站为了保护自身数据,会采取各种反爬虫技术来阻止爬虫的访问。Scrapy作为一个强大的爬虫框架,虽然能够高效地抓取网页数据,但在面对复杂的反爬虫机制时,仍然需要额外的工具来增强其反爬能力。Crawlera就是这样一款能够协助......
  • Python 爬取大量数据如何并发抓取与性能优化
    Python并发抓取与性能优化在进行网络爬虫开发时,爬取大量数据可能非常耗时。尤其是在处理许多网页或API请求时,逐个请求速度会非常慢。为了解决这个问题,我们可以通过并发抓取提高爬取效率。同时,通过性能优化来进一步减少耗时和资源占用,使爬虫更高效。本篇文章将带大家了解......
  • 使用Python中的DrissonPage库爬取小说网站并保存章节内容(bqg)
    前言在这个教程中,我们将学习如何使用Python结合DrissionPage库来自动化浏览器操作,从而从一个小说网站(bqg)上抓取小说的章节链接和内容,并将这些内容保存到本地文件。本文将详细介绍整个过程,并提供完整的代码示例。准备工作在开始之前,请确保已经安装了以下Python库:driss......
  • Python爬取豆瓣音乐top250
    importrequestsfrombs4importBeautifulSoupimportpandasaspdimporttimedefcrawl_douban_music_top250():data=[]base_url="https://music.douban.com/top250"foriinrange(0,250,25):url=f"{base_url}?start={......
  • 使用python爬虫爬取热门文章分析最新技术趋势
    本文借助爬虫来分析哪些技术正在快速发展,哪些问题在开发者中引起广泛讨论,从而为学习和研究提供重要参考。使用python爬虫分析最新技术趋势一、爬取目标二、代码环境2.1编程语言2.2三方库2.3环境配置三、代码实战3.1接口分析3.2接口参数分析接口地址请求方法描述......