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 

原文链接:https://blog.csdn.net/sdu_hao/article/details/96602032?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165277607816782395317734%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165277607816782395317734&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-13-96602032-null-null.nonecase&utm_term=%E6%96%B0%E9%97%BB

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
文明发言,共建和谐米科社区
提交
头像

昵称

取消
昵称表情图片