爬取新浪新闻[内容笔记代码整理]

学习视频:网易云 Python网络爬虫实战

环境:python3.5,requests,bs4,json,pandas,re,datetime

主要完成内容:爬取了新浪新闻-国内新闻版块的新闻信息,包括新闻标题,正文,编辑,发布时间和来源,并保存到excel中。使用Chrome的检查功能定位相关内容的位置。

需要用到的模块,这个相当于是初级教程,对每个模块的简单应用,具体细致的使用方法还需要再练习。

import requests
from bs4 import BeautifulSoup
from datetime import datetime
import json
import re

http://news.sina.com.cn/china/

先从一篇文章来分析

def getCommentCounts(newsurl):
    m =re.search('doc-i(.*).shtml',newsurl)
    newsid=m.group(1)
    comments = requests.get(commentURL.format(newsid))
    jd = json.loads(comments.text)
    return jd['result']['count']['total']
def getNewsDetail(newsurl):
    result = {}
    res = requests.get(newsurl)
    res.encoding = 'utf-8'
    soup = BeautifulSoup(res.text,'html.parser')
    result['title'] = soup.select(".main-title")[0].text
    result['newssource'] = soup.select(".source")[0].text
    timesource = soup.select(".date")[0].text
    result['dt'] = datetime.strptime(timesource,'%Y年%m月%d日 %H:%M')
    result['article'] =''.join([p.text.strip() for p in soup.select("#article p")[:-1]])
    result['editor']=soup.select(".show_author")[0].text.strip('责任编辑:')
    result['comments'] = getCommentCounts(newsurl)
    return result

这里需要对html结构的了解,以及对BeautifulSoup使用select方法的学习。

select方法可以通过标签名,类名,id名,组合,属性等方式进行查找。

爬取新浪新闻[内容笔记代码整理]_第1张图片爬取新浪新闻[内容笔记代码整理]_第2张图片

从上面的检查中可以看出,标题对应的内容包含在 class=“mian-title”中。因此,select中类名前面加点。同样的,对发布时间和来源也是在类中。

时间获取到的是文本格式的,可以利用datetime模块对时间格式进行转换。

爬取新浪新闻[内容笔记代码整理]_第3张图片

正文内容在 id=“article”下面,并且有多个段落。这里通过组合查找的方式,返回了全部符合的内容。

在文本处理中,strip()还是非常好用的,strip()用来移除字符串头尾指定的字符(默认为空格或换行)。lstrip(),rstrip()分别是对

获取文章评论总数

评论数不能直接从网页抓取,是从JavaScript链接上来的。

爬取新浪新闻[内容笔记代码整理]_第4张图片

这一段的链接为:

http://comment5.news.sina.com.cn/page/info?version=1&format=json&channel=gn&newsid=comos-hawmaua4736155&group=undefined&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=3&t_size=3&h_size=3&thread=1

标红部分对应了文章的编号。因此尝试获取这段内容,并且在移除多余字符以后,把json格式转换成字典格式。

{'article': '原标题:暴雨蓝色预警:重庆贵州等7省份部分地区有大雨或暴雨中国天气网讯 中央气象台5月22日06时继续发布暴雨蓝色预警:预计,22日08时至23日08时,重庆中南部、贵州东部、云南北部和东部、广西西部、湖南东北部、江西北部、浙中部等地的部分地区有大雨或暴雨,其中,重庆南部、贵州北部局地有大暴雨(100~140毫米);上述部分地区有短时强降水(20~40毫米,局地60毫米以上),局地有雷暴大风或冰雹等强对流天气。防御指南:1、建议政府及相关部门按照职责做好防御暴雨应急工作;2、切断有危险地带的室外电源,暂停户外作业;3、做好城市排涝,注意防范可能引发的山洪、滑坡、泥石流等灾害。',
 'comments': 0,
 'dt': datetime.datetime(2018, 5, 22, 6, 46),
 'editor': '余鹏飞 ',
 'newssource': '中国天气网',
 'title': '暴雨蓝色预警:重庆等7省份部分地区有大雨或暴雨'}

爬取当前页的所有文章链接

利用Chrome检查中的network监听,在国内新闻主页滚动的时候,页面存在非同步的载入。

爬取新浪新闻[内容笔记代码整理]_第5张图片

http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page=6&callback=newsloadercallback&_=1526954543004

通过preview的内容,可以发现这个内容包含了一个页面的所有文章信息。

res = requests.get('http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page=8&callback=newsloadercallback&_=1526880797249')
jd = json.loads(res.text.lstrip('  newsloadercallback(').rstrip(');'))
for ent in jd['result']['data']:
    print(ent['url'])

因此,根据一页产生的连接,我们可以把当前页的内容全部保存下来。

def parseListLinks(url):
    newsdetails = []
    res = requests.get(url)
    jd = json.loads(res.text.lstrip('  newsloadercallback(').rstrip(');'))
    for ent in jd['result']['data']:
        newsdetails.append(getNewsDetail(ent['url']))
    return newsdetails


建立多页连接

利用Chrome检查中的network监听,在切换页面时候,上面api的关键参数page可以控制。因此可以通过for循环快速产生多个分页清单的连接。用format()实现数据填充。

url = 'http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page={}&callback=newsloadercallback&_=1526880797249'
for i in range(1,10):
    newsurl = url.format(i)
    print(newsurl)

最后,根据分页连接,将每个分页的内容全部下载。

url = 'http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page={}&callback=newsloadercallback&_=1526880797249'
news_total = []
for i in range(1,3):
    newsurl = url.format(i)
    newsary = parseListLinks(newsurl) 
    news_total.extend(newsary)

保存到dataframe中。 head()可以查看表格内容。

import pandas as pd
df = pd.DataFrame(news_total)
df.head()

dataframe数据保存到文件中。

df.to_excel('sina_news.xlsx')

总结

一整套内容完成下来花的时间不多,要学会怎么去分析,怎么利用工具去分析。抓取的内容跟视频的讲解的已经有些变化,要自己清楚了解对应的关键位置,关键参数。

你可能感兴趣的:(爬虫)