Python學習日記:
1、編碼錯誤
UnicodeEncodeError: ‘ascii’ codec can’t encode
首先確認Python版本:
根據(jù)版本敲入對應的代碼
Python2.x:
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
<=Python 3.3:
import imp
imp.reload(sys)
>=Python 3.4:
import importlib
importlib.reload(sys)
查詢當前編碼:
sys.getdefaultencoding()
注:如果本來就是utf-8,則可能會報
AttributeError: 'module' object has no attribute 'setdefaultencoding' 的錯誤
本次遇到問題解析:網(wǎng)頁的URL中存在中文,刪掉后運行正常,可能是網(wǎng)頁中的URL 解析需要別的方式,用如下代碼后正常
urllib.parse.quote(word)
2、IndexError: list index out of range
情況一:
list[index]中的index下標超出范圍了,所以出現(xiàn)了訪問越界;
情況二:
list本身就是一個空的,沒有一個元素,所以當訪問到list[0]的時候,就會出現(xiàn)該錯誤。
猜測為情況二,修改py代碼,排除網(wǎng)頁權限問題,單頁爬取沒問題
3、爬取網(wǎng)頁表格
以爬取南儲為例,爬取后存到MySQL數(shù)據(jù)庫,完整代碼:
import requests
import pandas as pd
from bs4 import BeautifulSoup
from lxml import etree
import time
import pymysql
from sqlalchemy import create_engine
from urllib.parse import urlencode # 編碼 URL 字符串
start_time = time.time() #計算程序運行時間
def get_one_page(i):
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
}
# paras = {
# 'reportTime': '2019-7-31',
# #可以改報告日期,比如2018-6-30獲得的就是該季度的信息
# 'pageNum': i #頁碼
# }
url = 'http://www.enanchu.com/cu' + urlencode(paras)
response = requests.get(url,headers = headers)
if response.status_code == 200:
return response.text
return None
except RequestException:
print('爬取失敗')
def parse_one_page(html):
soup = BeautifulSoup(html,'lxml')
content = soup.select('#myTable04')[0] #[0]將返回的list改為bs4類型
tbl = pd.read_html(content.prettify(),header = 0)[0]
# prettify()優(yōu)化代碼,[0]從pd.read_html返回的list中提取出DataFrame
tbl.rename(columns = {'品名':'product_name', '價格區(qū)間':'price_range', '均價':'average_price', '漲跌':'up_and_down',
'日期':'date'},inplace = True)
# print(tbl)
return tbl
# rename將中文名改為英文名,便于存儲到mysql及后期進行數(shù)據(jù)分析
# tbl = pd.DataFrame(tbl,dtype = 'object') #dtype可統(tǒng)一修改列格式為文本
def generate_mysql():
conn = pymysql.connect(
host='localhost',
user='root',
password='19981019',
port=3306,
charset = 'utf8',
db = 'wade')
cursor = conn.cursor()
sql = 'CREATE TABLE IF NOT EXISTS test (product_name VARCHAR(50) NOT NULL,price_range VARCHAR(30) ,average_price INT(30) ,up_and_down INT(30) ,date DATETIME(0))'
# listed_company是要在wade數(shù)據(jù)庫中建立的表,用于存放數(shù)據(jù)
cursor.execute(sql)
conn.close()
def write_to_sql(tbl, db = 'wade'):
engine = create_engine('mysql+pymysql://root:19981019@localhost:3306/{0}?charset=utf8'.format(db))
try:
# df = pd.read_csv(df)
tbl.to_sql('test2',con = engine,if_exists='append',index=False)
# append表示在原有表基礎上增加,但該表要有表頭
except Exception as e:
print(e)
def main(page):
generate_mysql()
for i in range(1,page):
html = get_one_page(i)
tbl = parse_one_page(html)
write_to_sql(tbl)
# # 單進程
# if __name__ == '__main__':
# main(1)
# endtime = time.time()-start_time
# print('程序運行了%.2f秒' %endtime)
參考資料:
Python從入門到實踐:NameError: name 'reload' is not defined
stackoverflow
爬取一個gb2312的頁面
10行代碼爬取全國所有A股/港股/新三板上市公司信息