Python爬虫实战 | (13) 爬取新浪滚动新闻

在本篇博客中,我们将使用selenium爬取新浪新闻中滚动页面的所有新闻内容,包括题目、时间、来源、正文,并存入MongoDB数据库。网址:https://news.sina.com.cn/roll

打开后,发现这里都是一些滚动新闻,每隔1分钟就会刷新:

我们右键查看网页源代码,发现并没有当前页面的信息:

在源码页面搜索当前第一条新闻,并没有找到。

右键检查:

发现有当前页面的信息。说明当前页面是动态页面,即通过javascript渲染后得到的。因此,通过requests请求,是无法得到页面信息的,它得到的是网页最原始的代码,和右键查看网页源代码得到的是一致的。所以,我们需要使用selenium,模拟浏览器运行,来处理动态页面,从而爬取新闻信息。

程序主体框架如下:

import pymongo

import requests
from requests import RequestException
from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.common.exceptions import NoSuchElementException


def get_response(url):
    pass

def get_news(link):
    # 获取新闻的详细信息
    pass

def get_page_news():
    #获取当前页面所有新闻的url
    pass



    

if __name__ == '__main__':
    #连接mongodb
    client = pymongo.MongoClient('mongodb://localhost:27017')
    #指定数据库
    db = client.News
    #指定集合
    news_col = db.sinaRollNews
    #打开浏览器
    browser = webdriver.Chrome()
    browser.implicitly_wait(10)
    #打开网址
    browser.get('https://news.sina.com.cn/roll/')
    #获取当前页面新闻的url
    get_page_news()
    while True:
        try:
            #找到下一页按钮 并点击
            '''
            <a href="javascript:void(0)" onclick="newsList.page.next();return false;">下一页</a>
            '''
            browser.find_element_by_xpath('//a[@onclick="newsList.page.next();return false;"]').click()
            #获取下一页新闻的url
            get_page_news()
        except NoSuchElementException:
            print("NoSuchElementException")
            browser.close()
            break

右键检查当前页面,查看新闻的url:

def get_page_news():
    #获取当前页面所有包含新闻的a标签
    news = browser.find_elements_by_xpath('//div[@class="d_list_txt"]/ul/li/span/a')
    for i in news:
        link = i.get_attribute('href') #得到新闻url
        print(link,i.text)
        if not news_col.find_one({'link':link}):  #通过url去重
            get_news(link)

获取页面的详细信息:

我们发现首页是动态页面,点击一条新闻进去之后的页面并不是动态页面,所以可以使用requests进行爬取。首先爬取每条新闻的页面信息。


def get_response(url):
    try:
        #添加User-Agent,放在headers中,伪装成浏览器
        headers = {
            'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
        }
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            response.encoding = 'utf-8'
            return response.text
        return None
    except RequestException:
        return None

解析页面信息,获取每条新闻的详细信息:

新闻正文分布在下图div标签的每个p标签中:

def get_news(link):
    # 获取新闻的详细信息
    html = get_response(link)
    #使用beautifulsoup进行解析
    soup = BeautifulSoup(html,'lxml')

    #标题
    '''
    <h1 class="main-title">证监会要求北京银行说明是否串通*ST康得管理层舞弊</h1>
    '''
    title = soup.select('.main-title')
    #可能有小部分标题的标签不是上述格式 对其进行补充
    if not title:
        title = soup.select('#artibodyTitle')
    if title:
        title = title[0].text
    print(title)

    #日期
    '''
    <span class="date">2019年07月20日 16:52</span>
    '''
    date = soup.select('.date')
    # 可能有小部分日期的标签不是上述格式 对其进行补充
    if not date:
        date = soup.select('#pub_date')
    if date:
        date = date[0].text
    print(date)

    #来源
    '''
    <span class="source ent-source">中国证券报</span>
    '''
    source = soup.select('.source')
    # 可能有小部分来源的标签不是上述格式 对其进行补充
    if not source:
        source = soup.select('[data-sudaclick="media_name"]')
    if source:
        source = source[0].text
    print(source)

    #正文
    article = soup.select('div[class="article"] p')
    # 可能有小部分正文的标签不是上述格式 对其进行补充
    if not article:
        article = soup.select('div[id="artibody"] p')
    if article:
        #把正文放在一个列表中 每个p标签的内容为列表的一项
        article_list = []
        for i in article:
            print(i.text)
            article_list.append(i.text)
    #转为字典格式
    news = {'link': link, 'title': title, 'date': date, 'source': source, 'article': article_list}

    news_col.insert_one(news)

爬取效果:

完整代码:

import pymongo

import requests
from requests import RequestException
from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.common.exceptions import NoSuchElementException


def get_response(url):
    try:
        #添加User-Agent,放在headers中,伪装成浏览器
        headers = {
            'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
        }
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            response.encoding = 'utf-8'
            return response.text
        return None
    except RequestException:
        return None

def get_news(link):
    # 获取新闻的详细信息
    html = get_response(link)
    #使用beautifulsoup进行解析
    soup = BeautifulSoup(html,'lxml')

    #标题
    '''
    <h1 class="main-title">证监会要求北京银行说明是否串通*ST康得管理层舞弊</h1>
    '''
    title = soup.select('.main-title')
    #可能有小部分标题的标签不是上述格式 对其进行补充
    if not title:
        title = soup.select('#artibodyTitle')
    if title:
        title = title[0].text
    print(title)

    #日期
    '''
    <span class="date">2019年07月20日 16:52</span>
    '''
    date = soup.select('.date')
    # 可能有小部分日期的标签不是上述格式 对其进行补充
    if not date:
        date = soup.select('#pub_date')
    if date:
        date = date[0].text
    print(date)

    #来源
    '''
    <span class="source ent-source">中国证券报</span>
    '''
    source = soup.select('.source')
    # 可能有小部分来源的标签不是上述格式 对其进行补充
    if not source:
        source = soup.select('[data-sudaclick="media_name"]')
    if source:
        source = source[0].text
    print(source)

    #正文
    article = soup.select('div[class="article"] p')
    # 可能有小部分正文的标签不是上述格式 对其进行补充
    if not article:
        article = soup.select('div[id="artibody"] p')
    if article:
        #把正文放在一个列表中 每个p标签的内容为列表的一项
        article_list = []
        for i in article:
            print(i.text)
            article_list.append(i.text)
    #转为字典格式
    news = {'link': link, 'title': title, 'date': date, 'source': source, 'article': article_list}

    news_col.insert_one(news)


def get_page_news():
    #获取当前页面所有包含新闻的a标签
    news = browser.find_elements_by_xpath('//div[@class="d_list_txt"]/ul/li/span/a')
    for i in news:
        link = i.get_attribute('href') #得到新闻url
        print(link,i.text)
        if not news_col.find_one({'link':link}):  #通过url去重
            get_news(link)




if __name__ == '__main__':
    #连接mongodb
    client = pymongo.MongoClient('mongodb://localhost:27017')
    #指定数据库
    db = client.News
    #指定集合
    news_col = db.sinaRollNews
    #打开浏览器
    browser = webdriver.Chrome()
    browser.implicitly_wait(10)
    #打开网址
    browser.get('https://news.sina.com.cn/roll/')
    #获取当前页面新闻的url
    get_page_news()
    while True:
        try:
            #找到下一页按钮 并点击
            '''
            <a href="javascript:void(0)" onclick="newsList.page.next();return false;">下一页</a>
            '''
            browser.find_element_by_xpath('//a[@onclick="newsList.page.next();return false;"]').click()
            #获取下一页新闻的url
            get_page_news()
        except NoSuchElementException:
            print("NoSuchElementException")
            browser.close()
            break

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
新浪新闻采集程序天宇版 更新日志: v1.2 1、修复首及文章错误! 新浪滚动新闻采集程序天宇版简介 新浪新闻采集程序天宇版采用php进行开发,能自动对新浪新闻进行采集。 占用空间小,建站成本低,无需等待,马上就可以拥有海量网站数据; 免更新免维护,管理方便,操作简单,实现全站后台管理的全自动采集; 实现内容URL路径伪静态功能,让各大搜索引擎收录更加友好; 新浪滚动新闻采集程序天宇版功能介绍: 1.关键词内链 VIP 2.内容过滤 VIP 3.伪原创词汇 VIP 4.模板独立化(支持自己编写模板) 5.支持自定义路径伪静态(更好的搜索引擎亲和力)【无组件支持伪静态】 6.增加强大的缓存功能(极大降低UPU资源占用率) 7.增加蜘蛛访问记录(实时查看各大搜素引擎蜘蛛对网站爬行动态) 8.增加畅言评论功能 9.增加手机版VIP(自动识别手机与PC机访问切换) 10.自动采集百度搜索相关关键词(非常利于SEO) 后台登录admin/ 账号密码都为admin 上传后请及时更改后台登录路径(给admin文件夹重命名) 后续更新敬请期待。。。 广告不是一成不变的客户也可以自主在模板里直接添加广告代码 模板位置:/templets/default/ 带m的为手机版模板 新浪滚动新闻采集程序天宇版前台页面 新浪滚动新闻采集程序天宇版后台管理 后台登录admin/ 账号密码都为admin 后台页面 相关阅读 同类推荐:站长常用源码
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值