好 好 学 习,好 好 睡 觉

-->

数据采集第二次作业

作业1

实验过程

获取html

def getHTMLText(url):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
        }
        resp = requests.get(url=url, headers=headers)
        resp.encoding = resp.apparent_encoding  # 自适应解码
        return resp.text
    except:
        return 'error'

通过正则寻找相关信息

image
通过页面源码分析,发现日期,天气信息,最高温与最低温分别在h1,p,p标签中,则可以通过正则匹配对应信息

def find_data(data):
    date = []  # 存储日期
    mes = []  # 存储天气信息
    tmp = []  # 存储温度
    # 查找日期
    reg_date = r'<h1>(.*?)</h1>'
    res_date = re.findall(reg_date, data, re.S)  # 设置re.S模式
    # 查找天气信息
    reg_mes = r'<p title="(.*?)" class="wea">.*?</p>'
    res_mes = re.findall(reg_mes, data, re.S)
    # 查找最高温度以及最低温度
    reg_tem = r'<p class="tem">(.*?)</i>.*?</p>'
    res_tem = re.findall(reg_tem, data, re.S)
    for i in range(7):
        date.append(res_date[i])#添加日期
        mes.append(res_mes[i])#添加天气信息
        res_tem[i] = re.sub('<.*?>', '', res_tem[i])#正则替换包括在< >中所有的字符串成空
        res_tem[i] = re.sub('\n', '', res_tem[i])#把换行换成空
        tmp.append(res_tem[i])#添加温度信息
    return date, mes, tmp  #返回日期,天气信息,温度

数据保存

数据保存到数据库中,调用pymysql:

def Save_mysql():
    conn = pymysql.connect(host="localhost", user="root", password="123", database="task", charset='utf8') #连接,其中database为数据库名称
    cs1 = conn.cursor() #创建游标对象
    sqlcreate = '''
         create table if not exists exp2_1(
                序号 char(20) not null,
                日期 char(20) not null,
                地区 char(20) not null,
                天气信息 char(50) not null,
                温度 char(20) not null)
       '''
    cs1.execute(sqlcreate)
    sql = '''INSERT INTO exp2_1(序号, 日期, 地区, 天气信息, 温度) VALUES("%s","%s","%s","%s","%s")'''
    for i in range(7):
        arg = (i + 1, '北京', date[i], mes[i], tmp[i]) #设置存入信息
        cs1.execute(sql, arg)
        conn.commit()

用数据库可视化工具(Navicat)查看数据
image

实验心得

1.通过正则匹配中查找对应元素位置时要设置re.S模式,否则会有看不见的符号导致匹配失败。
2.使用pymysql时使用以前写的模板方便了自己,提醒了自己的代码的模块化,方便自己以后使用。

作业二

  • 要求: 用requests和自选提取信息方法定向爬取股票相关信息,并存储在数据库中。
    image
  • 候选网站:
    东方财富网:https://www.eastmoney.com/
    新浪股票:http://finance.sina.com.cn/stock/
  • 技巧:
    在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api
    返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、
    f2可获取不同的数值,根据情况可删减请求的参数。
    参考链接:https://zhuanlan.zhihu.com/p/50099084

实验过程

寻找js请求

image
先选中js文件,然后清空,在清空后刷新一下页面(方便观察)。
image
在Preview中可查看数据,找到对应的js包后,点击Headers
image
上图的Request URL便是我们要找的。
通过浏览器直接访问:
image

构造请求头,用requests.get()方法访问该ur获取html文本,与前面方法一致。

def getHTMLText(url):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
        }
        resp = requests.get(url=url, headers=headers)
        resp.encoding = resp.apparent_encoding  # 解码
        return resp.text
    except:
        return 'error'

正则匹配对应信息

image

在diff中的都是相关数据,我们要寻找的也就在其中
处理好参数与各个值的对应关系,通过正则匹配将数据爬取出来。举个例子:

    code = re.findall(r'"f12":"(.*?)"',data,re.S) #股票代码
    name = re.findall(r'"f14":"(.*?)"',data,re.S) #股票名称
    last_price = re.findall(r'"f2":(.*?),',data,re.S) #最新报价
    chg = re.findall(r'"f3":(.*?),',data,re.S) #涨跌幅
	......

数据保存

与题一的方法一致,调用pymysql保存数据。
用数据库可视化工具(Navicat)查看数据

image

实验心得

1.获取的HTML与我们看到的不一样,里面不含有数据,这时候应该知道审查中看到的可能是经过js渲染过的,故要寻找js包请求。
2.这和以前碰到的找js请求然后通过post传参访问url有一点区别,这种可以直接访问url。

作业三

实验步骤

寻找js请求

打开url只有第一页的学校信息,翻页过程url也没有发生变化,故考虑是附在js文件中生成的。
进行抓包:首先清空页面的js请求,然后刷新,再到js请求中去寻找相应的数据。

image

找到相应的url后,用requests.get()方法访问该ur获取html文本。与前面方法一致。

正则匹配信息

由于网页打开是乱码,故将其转码后输出,保存到txt文件中分析:
image

找到对应信息的结构,用正则匹配将其找到。

def find_data():
    # 正则匹配相关信息
    name = re.findall(r'univNameCn:"(.*?)"', data, re.S)
    score = re.findall(r'score:(.*?),', data, re.S)
    return name, score

数据保存

打印过程中发现其中有些学校并没有实际得分,是以字符串代替,便以null替换。
image

def print_data():
    print("{0:{ocp}<8}\t{1:{ocp}<20}\t{2:{ocp}<8}".format("排名", "名称", "总分", ocp=chr(12288)))
    for i in range(len(name)):
        # 如果score中的字符串无法强制转换为float,则用null代替
        try:
            float(score[i])
        except:
            score[i] = 'null'
        print("{0:{ocp}<8}\t{1:{ocp}<20}\t{2:{ocp}<8}".format(i + 1, name[i], score[i], ocp=chr(12288)))

转换后效果图:
image

存入数据库方法与前边作业一致,调用pymysql。

image

实验心得

1.页面解析还是不太懂,需要多多学习css,JavaScript等相关知识,这样能更好的了解页面渲染以及爬取相关数据。
2.通过F12抓包获取所有学校的信息,再用正则匹配寻找相关数据。让我对页面渲染和正则匹配有了更多的理解和体会。

代码地址

posted @ 2021-10-13 20:32  bInbinL  阅读(14)  评论(0编辑  收藏  举报