1. 程式人生 > >【Python爬蟲】requests+Beautifulsoup存入資料庫

【Python爬蟲】requests+Beautifulsoup存入資料庫

本次記錄使用requests+Beautiful+pymysql的方法將大學排名的資料存入本地MySQL資料庫。
這是一篇學習性文章,希望能夠分享在學習過程中遇到的坑與學到的新技術,試圖用最簡單的話來闡述我所記錄的Python爬蟲筆記。

一、爬取結果

儲存於MySQL資料庫結果如下:
這裡寫圖片描述

爬取結果在螢幕中列印如下:
這裡寫圖片描述

至於每行中間為什麼會有錯誤與失敗的字眼,稍後會進行解釋。

二、專案需求分析

此專案可解析為三個子問題:1、利用requests庫爬取網站所有內容
2、利用Beautifulsoup解析網站,提取需要
的內容。
3、 將提取的內容打印出來並存入資料庫。
因此定義四個函式:1、getHTMLtest( )
2、fillUnivList( )
3、printUnivList( )
4、main( )

三、實際程式碼解剖

開啟Spyder,匯入所需庫:

import requests
from bs4 import BeautifulSoup
import bs4
import pymysql

主函式編寫:

def main():
    uinfo = []
    url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 50) # 50 univs
main()      

getHTMLtest( )函式編寫:

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

此處採用requests庫中get函式將url中的內容全部抓取,此外還設定了timeout=30 引數,是為了不然網站查詢是爬蟲正在訪問。 r.raise_for_status()可檢查爬取是否成功,一般狀態碼為200則為爬取成功。r.encoding = r.apparent_encoding 修改備用編碼規則以防止出現亂碼。注意:此處使用了try…except的結構,這是為了讓你的程式碼更加安全可靠,不會因為這段程式碼出現問題而導致整個程式執行失敗。

fillUnivList( )函式編寫:

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string, tds[1].string, tds[3].string])

此處使用Beautifulsoup庫將爬取得內容進行解析。用find的方法找到所有的‘tbody’在使用.children的方法找到它的兒子標籤。if isinstance(tr, bs4.element.Tag) 此行程式碼是為了判斷‘tbody’的兒子標籤是否為tr,注意需要格外匯入bs4庫進行判斷。之後將內容寫入ulist列表。

printUnivList( )函式編寫:

def printUnivList(ulist, num):
    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","學校名稱","總分",chr(12288)))

    conn = pymysql.connect(host = 'localhost',port = 3306,user = 'root',
                       passwd = 'yourpasswd',db = 'university',charset = 'utf8')

    cur = conn.cursor()
    sqlc = '''
                create table DXPM(
                id int(11) not null auto_increment primary key,
                name varchar(255) not null,
                score float not null)DEFAULT CHARSET=utf8;

                '''
    try:
        cur.execute(sqlc)
        conn.commit()
        print("成功")
    except:
        print("錯誤")

    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))

        sqla = '''
        insert into  DXPM(id,name,score)
        values(%s,%s,%s);
       '''
        try:
            cur.execute(sqla,(u[0],u[1],u[2]))
            conn.commit()
            print("成功")
        except:
            print("失敗")



    conn.commit()
    cur.close()
    conn.close()

此段為核心程式碼,首先將排名,學校名稱,分數進行格式化輸出。使用以下程式碼連線你的資料庫,passwd換成你自己的mysql密碼。

conn = pymysql.connect(host = 'localhost',port = 3306,user = 'root',
                       passwd = 'yourpasswd',db =                     'university',charset = 'utf8')

·····································································································································
此處程式碼作用是為了使之前建立的資料庫表成功錄入資料庫,並且將資料寫入資料庫,若成功寫入列印成功,否則列印錯誤。由於之前筆者已經執行過此程式,也就是說本地資料庫中已經存在表與資料,所以之前的結果圖才會列印‘錯誤‘。最後記得將遊標與資料庫關閉.

    try:
        cur.execute(sqlc)
        conn.commit()
        print("成功")
    except:
        print("錯誤")

    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))

        sqla = '''
        insert into  DXPM(id,name,score)
        values(%s,%s,%s);
       '''
        try:
            cur.execute(sqla,(u[0],u[1],u[2]))
            conn.commit()
            print("成功")
        except:
            print("失敗")



    conn.commit()
    cur.close()
    conn.close()

四、原始碼

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 28 14:11:44 2017

@author: 追夢囚徒
"""
import requests
from bs4 import BeautifulSoup
import bs4
import pymysql

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string, tds[1].string, tds[3].string])

def printUnivList(ulist, num):
    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","學校名稱","總分",chr(12288)))

    conn = pymysql.connect(host = 'localhost',port = 3306,user = 'root',
                       passwd = 'yourpasswd',db = 'university',charset = 'utf8')

    cur = conn.cursor()
    sqlc = '''
                create table DXPM(
                id int(11) not null auto_increment primary key,
                name varchar(255) not null,
                score float not null)DEFAULT CHARSET=utf8;

                '''
    try:
        cur.execute(sqlc)
        conn.commit()
        print("成功")
    except:
        print("錯誤")

    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))

        sqla = '''
        insert into  DXPM(id,name,score)
        values(%s,%s,%s);
       '''
        try:
            cur.execute(sqla,(u[0],u[1],u[2]))
            conn.commit()
            print("成功")
        except:
            print("失敗")



    conn.commit()
    cur.close()
    conn.close()

最後希望本文能對你有所幫助(其實是對我自己有所幫助啦~),希望可以共同進步。
後續我會繼續更新爬蟲系列專題,文章都是作者學習過程中隨筆而記,不喜勿噴啊。