Python学习日记:
1、编码错误
UnicodeEncodeError: ‘ascii’ codec can’t encode
首先确认Python版本:
根据版本敲入对应的代码
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'
的错误
本次遇到问题解析:网页的URL
中存在中文,删掉后运行正常,可能是网页中的URL
解析需要别的方式,用如下代码后正常
urllib.parse.quote(word)
2、IndexError: list index out of range
情况一:
list[index]
中的index下标超出范围了,所以出现了访问越界;
情况二:
list本身就是一个空的,没有一个元素,所以当访问到list[0]
的时候,就会出现该错误。
猜测为情况二,修改py代码,排除网页权限问题,单页爬取没问题
3、爬取网页表格
以爬取南储为例,爬取后存到MySQL数据库,完整代码:
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()优化代码,[0]从pd.read_html返回的list中提取出DataFrame
tbl.rename(columns = {'品名':'product_name', '价格区间':'price_range', '均价':'average_price', '涨跌':'up_and_down',
'日期':'date'},inplace = True)
# print(tbl)
return tbl
# rename将中文名改为英文名,便于存储到mysql及后期进行数据分析
# tbl = pd.DataFrame(tbl,dtype = 'object') #dtype可统一修改列格式为文本
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数据库中建立的表,用于存放数据
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股/港股/新三板上市公司信息