Python学习日记(一)

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股/港股/新三板上市公司信息

你可能感兴趣的:(Python学习日记(一))