天天看點

整理一下百度新聞資料挖掘系統搭建的一種闆塊 前言代碼

 前言

今天講一下爬蟲實戰,用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="(.*?)" target="_blank" rel="external nofollow" '
    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 + '資料爬取并存入資料庫失敗')
           

記錄自己的學習生活并希望對你有所幫助,感謝!