Scrapy-网易新闻模块爬取

需求

首先明确需求:爬取网易新闻新闻的标题和新闻详情页的内容
注意项:

  • 先从首页获取对应的详情页的url
  • 每一个模块的新闻都是动态加载出来的,可配合selenium实现动态加载
  • 详情页面的爬取

实现过程

创建工程:scrapy startproject wangyiPro
转入工程:cd wangyiPro
创建爬虫文件:scrapy genspider wangyi www.xxx.com

实现过程

1.1 观察首页结构,定位模块

观察网易新闻的首页,配套开发者工具,定位到需要爬取的模块,编写parse方法获取url
wangyi.py

from selenium import webdriver
from wangyiPro.items import WangyiproItem
import scrapy

# 需求,爬取五大板块下的新闻内容和标题,内容在新闻详情页面中,标题在对应模块下
# 各个模块下的内容是 动态加载的  可配合selenium实现动态加载
# 详情页面的爬取

class WangyiSpider(scrapy.Spider):
    name = 'wangyi'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://news.163.com/']
    model_urls = []

    def parse(self, response):
        # 获取不同模块下的url,放入model_urls中
        li_list = response.xpath('//div[@class="ns_area list"]/ul/li')
        url_list = [2, 3, 5, 6, 10]
        for index in url_list:
          	# 不同模块下对应的url
            url = li_list[index]
            model_url = url.xpath('./a/@href').extract_first()
            self.model_urls.append(model_url)
            # 对不同模块下的url进行请求
            yield scrapy.Request(model_url, callback=self.parse_model) 

1.2 selenium实现动态加载

对不同模块的url发起请求后,不难发现新闻有个明显的加载,这个动态加载的表现,为获取到动态加载的数据,可配合selenium使用。
先在 wangyi.py文件中实例化一个浏览器对象
wangyi.py

# 实例化一个浏览器对象
    def __init__(self):
        # from selenium import webdriver
        self.options = webdriver.ChromeOptions()
        # 添加“取消侦听提示”的配置项
        self.options.add_experimental_option('excludeSwitches', ['enable-logging'])
        self.driver = webdriver.Chrome(executable_path=r"C:\Users\vidfu\PycharmProjects\wangyiPro\chromedriver.exe", options=self.options)

之后,在middlewares.py文件的WangyiproDownloaderMiddleware类中的process_response方法中编写代码
middlewares.py

# 拦截5个请求的响应体,进行篡改
    def process_response(self, request, response, spider):
        # spider 是爬虫对象
        # response 是响应对象
        # 实例化一个新的响应对象(符合所有需求,包括动态加载出数据),代替原来的响应对象
        # 问题-如何动态加载数据?:基于selenium获取动态加载的数据
        # 通过url指定request,request指定对应的response

        # 获取在爬虫类中定义的浏览器驱动对象
        bro = spider.driver
		# 拦截到的响应在5给模块中,就换一个新的响应体
        if request.url in spider.model_urls:
            # 获取请求
            bro.get(request.url)
            sleep(5)
            # 获取到的数据中包含了动态加载
            page_text = bro.page_source
			# from scrapy.http import HtmlRespon
			# 新的响应体
            new_response = HtmlResponse(url=request.url,
                                        body=page_text,
                                        encoding='utf-8',
                                        request=request)
            return new_response
        else:
            return response

1.3 发起请求,获取详情页内容

对1.1获取到的模块url发起请求,在items.py文件中设置字段,获取新闻标题和新闻内容,最后关闭驱动
wangyi.py

 	# 对不同模块url进行请求, 不同板块的新闻内容是动态加载的
    def parse_model(self, response):
        div_list = response.xpath('//div[@class="ndi_main"]/div')
        for div in div_list:
        	# 实例化item对象
            item = WangyiproItem()
            item['title'] = div.xpath('./div/div[1]/h3/a/text()').extract_first()
            detail_url = div.xpath('./div/div[1]/h3/a/@href').extract_first()
            yield scrapy.Request(detail_url, callback=self.parse_detail, meta={'item': item})
            
	# 对详情页面进行解析
    def parse_detail(self, response):
        item = response.meta['item']
        item['content'] = ''.join(response.xpath('//div[@class="post_body"]//text()').extract())
        yield item

	# 关闭开启的驱动
    def colse(self, spider):
        self.driver.quit()

1.4 设置配置文件

设置User-Agent、robots协议、日志等级、开启管道和中间件,要看一下爬取的内容,在管道类WangyiproPipeline打印出来
setting.py

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
LOG_LEVEL = 'ERROR'
DOWNLOADER_MIDDLEWARES = {
   'wangyiPro.middlewares.WangyiproDownloaderMiddleware': 543,
}
ITEM_PIPELINES = {
   'wangyiPro.pipelines.WangyiproPipeline': 300,
}

结果展示

在这里插入图片描述
遇到一个问题,虽然有打印输出,但是在打印之前会提示”typeerror: request url must be str or unicode, got nonetype“,我在想是我详情页面的url类型出错了吗?,我检查了一下,没检查出个所以然来,没影响输出就不管了,如果有大佬知道是怎么回事,欢迎评论留言。在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值