【Python-爬虫】使用Scrapy框架爬取某瓣的新书

目录

一.创建项目

二.代码呈现

1.更改配置文件-1

2.爬虫代码

3.保存数据 

4.更改配置文件-2


请求网址为:豆瓣-新书速递

在文章里展示全部的代码的话会非常影响文章的观看,有想要查看全部代码的朋友请到GitHub:GitHub - aqaswrae/Some-small-crawler-projects: python爬虫的一些小项目

 

这个就是 

想要收藏一下的,请点击一下右上角的小星星哦 谢谢大家

一.创建项目

首先要创建scrapy项目和爬虫文件,若有疑问,请看scrapy框架的基本使用这一篇文章

链接:Python爬虫-Scrapy框架的基本使用_瓦瓦卡卡的博客-CSDN博客

二.代码呈现

1.更改配置文件-1

1.删除roboots协议

创建好scrapy项目的第一步,就是先把***协议干掉

找到settings.py文件,将20行的roboots协议注释掉或者直接将其删除

将其注释掉或者删除掉
# ROBOTSTXT_OBEY = True

 2.伪造请求头

在settings.py文件中第40行设置

DEFAULT_REQUEST_HEADERS = {
   'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
   'Referer':'https://www.baidu.com/link?url=Ix_GYKtVB-za1RMzZb2tYUctsXsgV4OqJx3dfOpbJ7h-d2jUp5QAVmulA9v14Pfr&wd=&eqid=ea2fe0010001250a000000036497bcb9',
}

如果只设置user-agent的话,可以只更改第17行的USER_AGENT

2.爬虫代码

这次爬取的是豆瓣的新书速递        https://book.douban.com/latest

首先在items.py文件中做好数据建模

class DoubanbookscrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()   #书籍名称
    content = scrapy.Field()#书籍简介
    link = scrapy.Field()   #详情链接
    txt = scrapy.Field()    #点击详情链接后页面中的内容简介

 scrapy框架内置了xpath语法,所以我们使用xpath语法来获取所需的数据

    def parse(self, response):
        names = response.xpath('//ul[@class="chart-dashed-list"]/li/div[@class="media__body"]/h2/a/text()').extract()
        contents = response.xpath('//ul[@class="chart-dashed-list"]/li/div[@class="media__body"]/p[1]/text()').extract()
        links = response.xpath('//ul[@class="chart-dashed-list"]/li/div[@class="media__body"]/h2/a/@href').extract()

        for name,content,link in zip(names,contents,links):
            # 导入item.py中的类,然后实例化一个对象,将获取的数据传给item,键名必须和字段名统一
            item = DoubanbookscrapyItem()
            item['name'] = name
            item['content'] = content.strip()
            item['link'] = link
            #将数据返回给引擎
            #不请求详情页的内容简介时,使用 yield item
            yield item
            #需要将详情页的链接传给引擎请求详情页的数据时使用下面这个
            # yield scrapy.Request(url=item['link'],callback=self.parse_detail,meta={'item':item})

        #翻页
        page_url = response.xpath('//span[@class="next"]/a/@href').extract_first()
        #拼接完整的链接
        next_url = response.urljoin(page_url)
        # print('下一页的链接:',next_url)
        #构造请求对象,返回给引擎
        yield scrapy.Request(url=next_url,callback=self.parse)

       

 解析详情页的内容简介的逻辑与上边的函数不同,需要我们自己写另一个解析的函数;

        

#接下来用得到的书籍的链接来获取书籍详情页的内容简介,因为是不同的处理逻辑,所以我们要定义一个新的函数来处理详情页的数据
    def parse_detail(self,response):
        #内容简介
        t = response.xpath('//span[@class="all hidden"]//div[@class="intro"]//p/text()').extract()
        # print(t)
        item = response.meta['item']
        item['txt'] = ''.join(t)
        print(item)
        yield item

       

如果我们要解析详情页的数据,我们就要将详情页的链接构造成请求对象返回给引擎,这时我们就要将parse函数中的yield item 改为

yield scrapy.Request(url=item['link'],callback=self.parse_detail,meta={'item':item})

           

meta参数是专门用来传递数据的,规定使用字典形式;实现数据在不同的解析函数中传递

callback:表示当前的url的响应交给哪个函数去处理

3.保存数据 

 1.保存为json数据

pipelines.py文件中写保存数据的代码

保存数据要将settings.py文件的第66行的ITEM_PIPELINES解开

              

class DoubanbookscrapyPipeline:
    def __init__(self):
        self.file = open('doubannewbook.json','a',encoding='utf-8')

    def process_item(self, item, spider):
        dict_item = dict(item)
        #保存为json数据
        json_data = json.dumps(dict_item,ensure_ascii=False) + ',\n'
        self.file.write(json_data)
        return item

    def __del__(self):#del是当整个函数运行完之后再调用
        self.file.close()

                          

2.保存到MySQL数据库中

 要使用两种不同的方式保存数据时,我们需要再动手写一个保存到MySQL数据库中的类

自己写的其他的类需要到配置文件中设置好:在settings.py文件的第66行的ITEM_PIPELINES,将自己写的类添加到里面

ITEM_PIPELINES = {
   "doubanbookscrapy.pipelines.DoubanbookscrapyPipeline": 300,
   "doubanbookscrapy.pipelines.DoubanbookscrapyPipelineMysql": 301,
}

class DoubanbookscrapyPipelineMysql:#写好之后,要去settings.py文件对应的位置ITEM_PIPELINES设置好
    #连接MySQL数据库
    def __init__(self):
        self.db = pymysql.connect(
            host='localhost',
            user='root',
            password='123456',
            db='scrapy-spider',
            charset='utf8'
        )
        self.cur = self.db.cursor()

    def process_item(self, item, spider):
        dict_item = dict(item)
        try:
            sql = 'insert into doubanbook(name,content,link,txt) values(%s,%s,%s,%s)'
            self.cur.execute(sql,[item['name'],item['content'],item['link'],item['txt'],])
            self.db.commit()
            print('保存成功')
        except Exception as e:
            print(e)
            self.db.rollback()

        return item

    # close_spider:scrapy内置的方法,当所属类运行完成之后,这个方法就会运行,将cur和db关掉
    def close_spider(self):
        self.cur.close()
        self.db.close()

4.更改配置文件-2

这一步是挂代理和设置随机的UA,需要在middlewares.py文件中操作

middlewares.py文件中自己带的所有代码都不要动它,我们自己另外写

在最底行写相应的中间件

 process_request名字不可以更改 是scrapy规定的方法(协商机制)
 每个交给下载器的request对象都会经过该方法 并期望返回一个reposne

#挂代理
class Randomproxy:
    def process_request(self, request, spider):
        #挂上单个ip
        proxy = 'https://' + '42.177.139.217:4231'
        #修改请求的元数据,用于给其他组件传递信息
        request.meta['proxy'] = proxy
        #光这样设置好了还不可以,需要去settings.py文件中的53行的DOWNLOADER_MIDDLEWARES修改一下
        #"doubanbookscrapy.middlewares.Randomproxy": 542,

 如果要添加多个ip,需要设置一个多个ip的列表,使用random.choice(列表名)方法从中选取一个ip。

# 如果想挂多个ip
 # 随机IP
    ip_list = ['101.200.185.203:16817',
               '101.200.285.203:13817']
    def process_request(self, request, spider):
        # 挂随机IP
        p = random.choice(self.ip_list)
        # 修改请求的元数据字典 用于给框架中其他组件传递信息 比如添加代理
        request.meta['proxy'] = 'https://'+p

写好这个中间件后我们需要到settings.py文件中配置它

DOWNLOADER_MIDDLEWARES = {
   # "doubanbookscrapy.middlewares.DoubanbookscrapyDownloaderMiddleware": 543,
   "doubanbookscrapy.middlewares.Randomproxy": 542,
}

           

设置随机UA也是同理,只不过要将之前设置好的请求头注释掉

注意使用的是headers

request.headers['User-Agent'] = random.choice(self.user_agent)

而不是

request.meta['User-Agent'] = ......
#设置随机ua
class Randomuseragent:
    # 设置一个ua池
    user_agent = [自己添加User-Agent]
    def process_request(self, request, spider):
        request.headers['User-Agent'] = random.choice(self.user_agent)#这个地方要注意是headers
        #然后也需要到settings.py文件中的DOWNLOADER_MIDDLEWARES中设置"doubanbookscrapy.middlewares.Randomuseragent": 543,
        #ip的权重应比ua重
        #这样设置ua的话要在settings.py中的DEFAULT_REQUEST_HEADERS中,将ua给注释掉

更改配置文件

DOWNLOADER_MIDDLEWARES = {
   # "doubanbookscrapy.middlewares.DoubanbookscrapyDownloaderMiddleware": 543,
   "doubanbookscrapy.middlewares.Randomproxy": 542,
   "doubanbookscrapy.middlewares.Randomuseragent": 544,
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值