(六)基於Scrapy爬取網易新聞中的新聞數據


 

 

 

需求:爬取這國內、國際、軍事、航空、無人機模塊下的新聞信息

 

1.找到這五個板塊對應的url

 

 

 

 2.進入每個模塊請求新聞信息

 

我們可以明顯發現‘’加載中‘’,因此我們判斷新聞數據是動態加載出來的。

 

3.拿到新聞的標題和詳情url

 

4.請求詳情頁 獲取新聞內容

 

 

5.思路:思路已經很清晰了,請求五大板塊拿到五大板塊的詳情頁,獲取每一個板塊下的新聞標題和新聞詳情頁url,再對新聞詳情頁請求拿到新聞的內容。

需要注意的一點是,新聞都是動態加載出來的,因此我們用selenium來抓取新聞的數據。

6.代碼實現

爬蟲文件: wangyi.py

 

# -*- coding: utf-8 -*-
import scrapy
from selenium import webdriver
from wangYi.items import WangyiItem

class WangyiSpider(scrapy.Spider):
    name = 'wangyi'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://news.163.com/']
    urls = []
    def __init__(self):
        self.bro = webdriver.Chrome(executable_path='D:\OldBoy_Luffy\code_practice\chapter11\爬蟲\scrapy框架\chromedriver.exe')

    def parse(self, response):
        li_list = response.xpath('//*[@id="index2016_wrap"]/div[1]/div[2]/div[2]/div[2]/div[2]/div/ul/li')
        # 五大模塊所在li標簽的索引
        index_list = [3,4,6,7,8]

        # 獲取五大模塊的url
        for index in index_list:
            model_src = li_list[index].xpath('./a/@href').extract_first()
            self.urls.append(model_src)

        # 發送請求
        for url in self.urls:
            yield scrapy.Request(url=url, callback=self.parse_model)

    def parse_model(self,response):
        item = WangyiItem()
        # 每條新聞所在的div標簽
        div_list = response.xpath('/html/body/div/div[3]/div[4]/div[1]/div/div/ul/li/div/div')
        for div in div_list:
            # 獲取標題與詳情頁的url
            title = div.xpath('./div/div[1]/h3/a/text()').extract_first()
            detail_url = div.xpath('./div/div[1]/h3/a/@href').extract_first()
            item['title'] = title
            # 部分的新聞中可能會有廣告信息 因此可能會匹配為空  跳過循環
            if detail_url is None:
                continue
            # 請求詳情頁  請求傳參
            yield scrapy.Request(url=detail_url, callback=self.detail_parse,meta={'item':item})

    def detail_parse(self,response):
        item = response.meta['item']
        # 獲取新聞內容
        content = response.xpath('//div[@id="endText"]//text()').extract()
        content = ''.join(content)
        item['content'] = content
        # 存入管道
        yield item

    def closed(self,spider):  # 重寫父類方法 爬蟲結束時執行
        self.bro.quit()

 

中間件middlewares.py

  def process_response(self, request, response, spider):  # spider就是爬蟲文件中 爬蟲類的實例化對象
        # 拿到瀏覽器對象
        bro = spider.bro
        if request.url in spider.urls:
            # 獲取動態加載的數據
            bro.get(request.url)
            page_text = bro.page_source
            # 封裝成響應對象返回
            new_response = HtmlResponse(url=request.url,body=page_text,encoding='utf-8',request=request)
            return new_response
        else:
            return response

items.py

class WangyiItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    content = scrapy.Field()

pipelines.py

class WangyiPipeline:
    def open_spider(self,spider):
        self.fp = open('news.txt','w',encoding='utf-8')
        print('爬取開始...')

    def process_item(self, item, spider):
        title = item['title']
        content = item['content']
        if title is None:
            title=''
        if content is None:
            content = ''
        self.fp.write(title+'\n'+content)
        return item

    def close_spider(self,spider):
        self.fp.close()
        print('爬取結束')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM