BeautifulSoip+pandas 爬取新浪国内新闻

(1)使用技术

python 3.5.2、sqlite3、pandas、requests、jupyter notebook

(2)详细代码

新浪国内新闻首页:http://news.sina.com.cn/china/

1、爬取的内容为最新消息里面每个新闻详细页面的标题、发布时间、编辑、内容、评论数以及评论内容

2、编写思路

  • 使用requests将发送请求,并且将返回的数据接收回来。
  • 对接接收回来的数据进行处理,使用pandas进行处理,并且保存到sqlite3里面

3、具体的代码模块讲解

获取分页的url,国内新闻采取分页的形式来分割不同的新闻,因此我们首先获取新闻分页的数据,并且从分页的数据中获取到各个新闻详情页的url。getPageUrl用来获取分页的url(pageUrl 是在开发者工具使用NetWork查找到的,一般的请求在doc、js、xhr中)

def getPageUrl(begin,end):
    pageUrls = []
    pageUrl = "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={}"
    for i in range(begin,end):
        newUrl = pageUrl.format(i)
        pageUrls.append(newUrl)
    return pageUrls

根据获取到的分页的数据,再获取详情页面的URL,其中getNewsUrl中的begin,end是分页的开始和结束。由于新闻量的数据量太大,此处做了限制。

def getNewsUrl(begin,end):
    newsUrl = []
    pageUrls = getPageUrl(begin,end);
    for url in pageUrls:
        res = requests.get(url)
        res.encoding = "utf-8"
        urlJson = json.loads(res.text)
        for i in urlJson["result"]["data"]:
            newsUrl.append(i["url"])
    return newsUrl;

获取到了具体的新闻页面url以后,可以根据url去爬取新闻页面具体的信息。

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

def getNewDetails(newsUrl):
    results = {};
    contentsList = [];
    res = requests.get(newsUrl);
    res.encoding = "utf-8";
    soup = BeautifulSoup(res.text,"html.parser");
    mainTitle = soup.select(".main-title")[0].text.strip();
    results["mainTitle"] = mainTitle
    originTime = soup.select(".date-source span")[0].text.strip();
    publishTime = datetime.strptime(originTime,"%Y年%m月%d日 %H:%M");
    strTime = datetime.strftime(publishTime,"%Y-%m-%d");
    results["publishTime"] = publishTime
    if(len(soup.select(".date-source a")) > 0):
        originSource = soup.select(".date-source a")[0].text.strip();
    else:
        originSource = "";
    results["originSource"] = originSource
    contents = " ".join([p.text.strip() for p in soup.select(".article p")[:-1]]);
    results["contents"] = contents
    editor = soup.select(".article p")[-1].text.strip();
    results["editor"] = editor
    m = re.search("doc-i(.*).shtml",newsUrl)
    comments = requests.get("http://comment5.news.sina.com.cn/page/info?version=1\
    &format=json&channel=gn&newsid=comos-" + m.group(1) + "&group=undefined&compress=0\
    &ie=utf-8&oe=utf-8&page=1&page_size=3&t_size=3&h_size=3&thread=1");
    comments.encoding = "utf-8";
    commentsJson = json.loads(comments.text.strip());
    results["total"] = commentsJson["result"]["count"]["total"]
    for com in commentsJson["result"]["cmntlist"]:
        contentsList.append(com["time"] + " " + com["nick"] + ":" + com["content"])
    results["contents"] = ' '.join(contentsList)
    return results

用getNewData来做一个获取具体页面url以及爬取数据的一个连接

def getNewData():
    newsData = []
    newsUrl = getNewsUrl(1,3)
    for url in newsUrl:
        newsData.append(getNewDetails(url))
    return newsData

  • 使用pandas来处理返回来的数据,可以保存成csv,xlsx

import pandas;
df = pandas.DataFrame(getNewData())
df.to_excel("news.xlsx")

使用pandas来处理返回来的数据,可以保存数据库中

import sqlite3 
cnx = sqlite3.connect('news.sqlite')
type(cnx)
df.to_sql('data',cnx ,schema=None, if_exists='replace', index=True, index_label=None, chunksize=None, dtype=None)

读取数据库中的数据

import sqlite3;

pandas.read_sql('select * from data;',con = db)

本文根据自己的学习所总结的一些内容,如有不足之处,请多多指教。

版权声明: 原创文章,如需转载,请注明出处! https://blog.csdn.net/lwx356481/article/details/81216490

猜你喜欢

转载自blog.csdn.net/lwx356481/article/details/81216490