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