整理一下百度新闻数据挖掘系统搭建的一种板块

 前言

今天讲一下爬虫实战,用Python爬取百度新闻。本文用到的知识点: 
-requests 
-re正则表达式 

-MYSQL数据库

-time库

代码

  1. 获取网页源代码
  2. 编写正则表达式提炼内容
  3. 数据清洗
  4. 编写舆情评分及数据深度清洗
  5. 打印清洗后的数据
  6. 将数据存入数据库及数据去重
  7. 批量爬取多家公司新闻舆论方式
import requests
import re
import pymysql
import time

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
#此处为模拟浏览器访问,即用户代理,可在浏览器地址栏输入‘about:version’得到

def baidu(company):
    # 1.获取网页源代码
    url = 'https://www.baidu.com/s?tn=news&rtt=4&bsst=1&cl=2&wd=' + company  
    # 其中设置rtt=4则为按时间排序,如果rtt=1则为按焦点排序
    res = requests.get(url, headers=headers, timeout=10).text
    #timeout为等待响应时间
    # 2.编写正则提炼内容
    p_href = '<h3 class="c-title">.*?<a href="(.*?)"'
    p_title = '<h3 class="c-title">.*?>(.*?)</a>'
    p_info = '<p class="c-author">(.*?)</p>'
    href = re.findall(p_href, res, re.S)
  #findall()函数为查找,使用方式为re.findall(匹配规则,原始文本,re.S)
  #此处的修饰符参数re.S可以使得.*?  (.*?)可以匹配到换行
    title = re.findall(p_title, res, re.S)
    info = re.findall(p_info, res, re.S)

    # 3.数据清洗
    source = []  # 先创建两个空列表来储存等会分割后的来源和日期
    date = []
    for i in range(len(title)):
        title[i] = title[i].strip()
        title[i] = re.sub('<.*?>', '', title[i])
        info[i] = re.sub('<.*?>', '', info[i])
        source.append(info[i].split('&nbsp;&nbsp;')[0])
        date.append(info[i].split('&nbsp;&nbsp;')[1])
        source[i] = source[i].strip()
        date[i] = date[i].strip()

        # 统一日期格式
        date[i] = date[i].split(' ')[0]    #此处以空格来分割
        date[i] = re.sub('年', '-', date[i])
        date[i] = re.sub('月', '-', date[i])
        date[i] = re.sub('日', '', date[i])
        if ('小时' in date[i]) or ('分钟' in date[i]):
            date[i] = time.strftime("%Y-%m-%d")   #今天的日期
        else:
            date[i] = date[i]

    # 4.舆情评分及数据深度清洗
    score = []  先创建一个空列表
    keywords = ['违约', '诉讼', '兑付', '诽谤', '亏损', '不利']
    for i in range(len(title)):
        num = 0
        try:
            article = requests.get(href[i], headers=headers, timeout=10).text
        except:
            article = '爬取失败'

        try:
            article = article.encode('ISO-8859-1').decode('utf-8')
        except:
            try:
                article = article.encode('ISO-8859-1').decode('gbk')
            except:
                article = article
      #注意若网页实际的编码方式为gbk,则使用decode()函数解码时设置为utf-8会报错

        p_article = '<p>(.*?)</p>'
        article_main = re.findall(p_article, article)  # 获取<p>标签里的正文信息
        article = ''.join(article_main)  # 将列表转换成为字符串  
        for k in keywords:
            if (k in article) or (k in title[i]):
                num -= 5
        score.append(num)
        # 数据深度清洗
        company_re = company[0] + '.{0,5}' + company[-1]
        if len(re.findall(company_re, article)) < 1:
            title[i] = ''
            source[i] = ''
            href[i] = ''
            date[i] = ''
            score[i] = ''
    while '' in title:
        title.remove('')
    while '' in href:
        href.remove('')
    while '' in date:
        date.remove('')
    while '' in source:
        source.remove('')
    while '' in score:
        score.remove('')
   #此处意思是如果能找到相关内容,则通过findall()获得的列表长度就大于1;如果没找到则列表长度小于 
   #1,这样就可以执行将该新闻赋值为空值然后清除的操作了。


    # 5.打印清洗后的数据
    for i in range(len(title)):
        print(str(i + 1) + '.' + title[i] + '(' + date[i] + ' ' + source[i] + ')')
        print(href[i])
        print(company + '该条新闻的舆情评分为' + str(score[i]))

    # 6.将数据存入数据库及数据去重
    for i in range(len(title)):
        db = pymysql.connect(host='localhost', port=3306, user='root', password='', database='pachong', charset='utf8')
        cur = db.cursor()  # 获取会话指针,用来调用SQL语句

        # 6.1 查询数据,为之后的数据去重做准备
        sql_1 = 'SELECT * FROM article WHERE company =%s'
        cur.execute(sql_1, company)
        data_all = cur.fetchall()
        title_all = []
        for j in range(len(data_all)):
            title_all.append(data_all[j][1])

        # 6.2 判断数据是否在原数据库中,不在的话才进行数据存储
        if title[i] not in title_all:
            sql_2 = 'INSERT INTO article(company,title,href,source,date,score) VALUES (%s,%s,%s,%s,%s,%s)'  # 编写SQL语句
            cur.execute(sql_2, (company, title[i], href[i], source[i], date[i], score[i]))  # 执行SQL语句
            db.commit()  # 当改变表结构后,更新提交数据表
        cur.close()  # 关闭会话指针
        db.close()  # 关闭数据库链接
   


# 7.批量爬取多家公司
companys = ['华能信托', '阿里巴巴', '百度集团', '腾讯', '京东']
for company in companys:
    try:
        baidu(company)
        print(company + '数据爬取并存入数据库成功')
    except:
        print(company + '数据爬取并存入数据库失败')

记录自己的学习生活并希望对你有所帮助,感谢!

猜你喜欢

转载自blog.csdn.net/weixin_45973206/article/details/106960978
今日推荐