Scrapy爬取网易新闻

前言

        为了更加熟练的应用Scrapy,可以爬取一下网易新闻的导航栏各个模块的详情页内容试试手

1.下载Scrapy和selenium以及浏览器驱动,并将其初始化

        想要了解selenium和scrapy可以去看看我之前的内容介绍

https://blog.csdn.net/Tudective/article/details/136853389?spm=1001.2014.3001.5502

        https://blog.csdn.net/Tudective/article/details/136765867?spm=1001.2014.3001.5502

import scrapy
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from fiveBlood.items import FivebloodItem



class FiveSpider(scrapy.Spider):
    name = "five"
    start_urls = ["https://news.163.com/"]

    # 储存导航栏模块的url
    model_urls=[]

    # 初始化浏览器对象
    def __init__(self):
        # 初始化浏览器
        s = Service("D:\Program Files (x86)\chrome\chromedriver.exe")
        self.bro = webdriver.Chrome(service=s)

        1.1 setting.py基本设置

               在setting.py 关闭ROBOTSTXT_OBEY和日志信息,填写USER_AGENTH和日志信息

ROBOTSTXT_OBEY = False

LOG_LEVEL='ERROR'

USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"

2.定位爬取导航栏模块的URL

        建立一个model_urls来储存爬取的url,通过F12和xpath定位到模块的标签,在循环通过request对模块发起请求

    def parse(self, response):
        # 定位导航栏各个模块的url
        li_list=response.xpath('//*[@id="index2016_wrap"]/div[3]/div[2]/div[2]/div[2]/div/ul/li')

        # 将需要爬取的导航栏模块的下标储存在列表中
        alist=[1,2]
        for index in alist:
            model_url=li_list[index].xpath('./a/@href').extract_first()
            self.model_urls.append(model_url)

        # 向爬取的url发起请求,并回调到parse_model()方法中
        for url in self.model_urls:
            yield scrapy.Request(url=url,callback=self.parse_model)

3.获取新闻URL和标题

        首先通过F12发现标题和响应详情页内容URL结构层次,都在一个DIV标签内,然后便通过xpath定位,并将其储存到item对象中

        item对象中所存储的值

import scrapy


class FivebloodItem(scrapy.Item):
    # define the fields for your item here like:
    # 设置item中储存的response的内容
    title = scrapy.Field()
    content = scrapy.Field()
    # pass

     然后就要将item数据传递到详情页中去

# 解析每个版面中新闻的内容和标题
    def parse_model(self,response):
        div_list=response.xpath('/html/body/div/div[3]/div[3]/div[1]/div[1]/div/ul/li/div/div')
        for div in div_list:
            title=div.xpath('.//h3/a/text()').extract_first()
            new_detail_url=div.xpath('./a/@href').extract_first()
            # 创建item对象,将数据解析到item中去
            item=FivebloodItem()
            item['title']=title
            # 通过meta参数,把item这个字典只给‘key’,将parse_model的response传递给parse_detail中去
            yield scrapy.Request(url=new_detail_url,callback=self.parse_detail,meta={'item':item})

4.获取详情页的内容

        这里注意一下extract()和extract_first()的区别,由于内容里边可能第一个列表不会包含全部的内容,所以使用extract()返回内容列表

# 解析新闻内容
    def parse_detail(self, response):
        # extract():这个方法返回的是一个数组list,,里面包含了多个string,如果只有一个string,则返回['ABC']这样的形式。
        # extract_first():这个方法返回的是一个string字符串,是list数组里面的第一个字符串。
        content=response.xpath('//*[@id="content"]/div[2]//text()').extract()
        # 将列表内容转换为字符串
        content=" ".join(content)
        # 消除里边的空格和换行符
        content=content.replace('\n', '').replace('\r', '')

        # 储存到item中去
        item=response.meta['item']
        item['content']=content

        # 最终将所有response存储到item中,由item提交到管道类中去
        yield item

在详情页网址中的去F12定位到内容的标签地址

        然后关闭一下开始创建的浏览器对象

# 关闭浏览器对象
    def closed(self,spider):
        self.bro.quit()

5.在中间件中拦截响应

        详情页的内容可能是动态数据,可以对发起的请求进行拦截,scrapy有五大核心模块,想要了解可以去看看

https://blog.csdn.net/Tudective/article/details/136952793?spm=1001.2014.3001.5502

from scrapy import signals

# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter

from time import sleep

import random

from  scrapy.http import HtmlResponse
class FivebloodDownloaderMiddleware:

    # 拦截请求
    def process_request(self, request, spider):

        return None


    # 拦截响应
    def process_response(self, request, response, spider):
        # 获取在five文件中创建的爬虫类中的浏览器对象
        bro=spider.bro
        # 挑选出指定的响应对象进行更改,即各个模块的url
        if request.url in spider.model_urls:
            bro.get(request.url)
            # 浏览器停留等待防止,防止加载过快,未解析到数据
            sleep(5)
            # 包含动态数据
            page_text=bro.page_source
            # HtmlResponse作为Response构造方法,能够对HTML内容进行解析
            new_response=HtmlResponse(url=request.url,body=page_text,encoding='utf-8',request=request)

            return new_response
        else:
            return response




    # 拦截异常
    def process_exception(self, request, exception, spider):
      pass

然后在setting.py文件中打开这几个管道类

6.对数据进行持久化储存

        在pipelines.py文件去执行储存操作

from itemadapter import ItemAdapter


class FivebloodPipeline:
    fp = None

    # 对爬取的数据进行储存
    # 重写一个父类的方法:该方法只会在开始爬虫的时候执行一次
    def open_spider(self, spider):
        print("开始爬虫》》》》")
        # 保存在当前文件WyNews.txt中
        self.fp = open('./WyNews.txt', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        title = item['title']
        content = item['content']

        self.fp.write(title + ':' + content + '\n')

        # 传递给下一个即将被执行的管道类
        return item

    def close_spider(self, spider):
        print("结束爬虫》》》》")
        self.fp.close()

7.运行爬取

        在命令行cd切换到自己的项目路径,输入scrapy crawl ‘项目名‘ ,回车运行

        

期间就能看到selenium和scrapy对数据进行爬取

最后是爬取的结果

  • 44
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值