python爬虫优化和错误日志分析(代码片段)

wanli002 wanli002     2022-12-09     294

关键词:

发现问题

在爬虫下载过程中,执行一段时间后都会异常终止,下次必须kill掉进程重新运行 ,看能否优化并减少手动操作

错误日志分析

收集了nohup.out文件,发现主要错误是的数组下标越界,推测可能的问题为:
1)网络不稳定,http请求不通。
2)网络请求成功,但是html表单解析失败。
3)登录的cookie过期

优化思路

在所有有网络请求的地方,都加上了返回码是不是200的判断,然后html表单解析的地方加上数组长度判断,异常处理等

源码如下

import socket
import time
import os
from datetime import datetime
import re
import yaml
import requests
from bs4 import BeautifulSoup

# 设置超时时间为10s
socket.setdefaulttimeout(10)
s = requests.Session()


# 登录
def login():
    url = host_url + "j_spring_security_check"

    data = 
        "username": bzh_host_usr,
        "password": bzh_host_pwd
    

    try:
        response = s.post(url, data=data, headers=headers)
        if response.status_code == 200:
            cookie = response.cookies.get_dict()
            print("login success")
            return cookie
    except Exception as e:
        print("login fail:", e)


# 页码
def get_pages():
    try:
        response = s.get(noticeListUrl, data=paramsNotice, headers=headers, cookies=cookie)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, "html.parser")
            pageCount = int(soup.find('span', id='PP_countPage').get_text())
            pageCount = pageCount if pageCount > 1 else 1
            return pageCount
    except Exception as e:
        print("get page_count fail:", e)


# 文档ids
def get_ids(pageCount):
    ids = []
    for p in range(int(pageCount)):
        paramsNotice['pageIndex'] = p + 1

        try:
            response = s.get(noticeListUrl, data=paramsNotice, headers=headers, cookies=cookie)
            if response.status_code == 200:
                soup = BeautifulSoup(response.text, "html.parser")
                trs = soup.find("table", class_='ObjectListPage').tbody.find_all("tr")
                regex = re.compile(r"noticeId=(\\d+)")

                for tr in trs:
                    if (tr.text.find("标准化文档更新") > 0):
                        id = regex.findall(str(tr))[0]
                        ids.append(id)
                        print("bzh id:" + id)

                        last_update = tr.find_all("td")[1].get_text().strip()
                        date_format = time.strftime("%Y%m%d", time.strptime(last_update, "%Y-%m-%d %H:%M:%S"))
                        file_name = "标准化文档-" + date_format + ".rar"

                        crawlFile(id, file_name)

        except Exception as e:
            print("get ids fail:", e)

    return ids


# 下载
def crawlFile(id, file_name):
    down_url = noticeURL + id
    metaFile = "./bzh/" + file_name

    response = s.get(down_url, headers=headers, cookies=cookie)
    content = response.headers.get('Content-Disposition')
    filename = content[content.find('=') + 1:]
    filename = filename.encode('iso-8859-1').decode('GBK')

    print("remote:" + filename)

    try:
        f = open(metaFile, 'wb')
        f.write(response.content)
        f.close()

        print(file_name + " first download success")
        exit(0)
    except Exception as e:
        print(file_name + " download fail", e)


if __name__ == "__main__":
    yaml_path = os.path.join('../', 'config.yaml')
    with open(yaml_path, 'r') as f:
        config = yaml.load(f, Loader=yaml.FullLoader)

    host_url = config['host_url']
    noticeListUrl = host_url + config['noticeListUrl']
    noticeDetailUrl = host_url + config['noticeDetailUrl']
    noticeURL = host_url + config['noticeURL']

    bzh_host_usr = config['bzh_host_usr']
    bzh_host_pwd = config['bzh_host_pwd']
    table_meta_bg_date = config['table_meta_bg_date']

    # header头信息
    headers = 
        "User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language": "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3",
        "Referer": host_url + "login.jsp"
    

    paramsNotice = 
        "queryStartTime": table_meta_bg_date
    

    task_begin = datetime.now()
    print("Crawler begin time:" + str(task_begin))

    cookie = login()
    if cookie == "":
        print("cookie is null")
        exit(0)

    pageCount = get_pages()

    pageCount = 2
    if pageCount < 1:
        print("page < 1")
        exit(0)

    ids = get_ids(pageCount)

    task_end = datetime.now()
    print("Crawler end time:" + str(task_end))

执行结果分析

优化后的爬虫运行正常,之前的异常已被捕获,输出在error日志里。
更新过的代码在线上环境跑了4天,收集了4天的错误日志,想从时间点上观察,看能否继续优化。
技术图片

源码如下

import os
import matplotlib.pyplot as plt

if __name__ == "__main__":
    print("analyze error of bzh crawler")

    error_con = 
    error_html = 
    for i in range(0, 24):
        key = "0" + str(i) if i < 10 else str(i)
        error_con[key] = 0
        error_html[key] = 0

    error_file = os.popen('ls ' + "./input").read().split()
    for i in range(0, len(error_file)):
        input = open('./input/' + error_file[i], 'r')

        for line in input:
            lines = line.split()
            error_msg = line[line.find("-", 50) + 2:]
            hour = lines[2][0:2]

            if error_msg.find("get html failed") > -1:
                error_con[hour] += 1
            elif error_msg.find("parse detail html failed") > -1:
                error_html[hour] += 1 / 2

    # 折线图
    plt.title("Plot of Error Hour Analyze(20190507-20190510)")
    plt.xlabel("Hour")
    plt.ylabel("Error Count")

    plt.plot(error_con.keys(), error_con.values(), color="r", linestyle="-", marker="^", linewidth=1, label="connect")
    plt.plot(error_html.keys(), error_html.values(), color="b", linestyle="-", marker="s", linewidth=1,
             label="parse html")
    plt.legend(loc='upper left', bbox_to_anchor=(0.55, 0.95))

    plt.show()

输出折线图

技术图片

  • connect连接失败的次数明显多于parse解析失败,因为连接失败第一个页面就进不去了,也不存在后面的html解析
  • 在连接正常的情况下,解析失败的次数占少数,4天的日志汇总,最多在1个小时里出现2次
  • 2个折线图的走势基本一致,符合预期
  • 折线图出现3个高峰,分别在凌晨4点,早上8点,晚上9点,推测远程服务器可能会定期重启,后期考虑是否加上爬虫时间过滤,晚上不执行来削峰
  • 现在只有4天的日志,执行一段时间后收集长时间的日志,再观察是否和星期,天数,月份有关等

python爬虫代码更新(代码片段)

昨天和室友看《Python 金融大数据挖掘与分析全流程详解》第67,68页的代码时,发现网页已经更新了,代码运行错误。先看结果,大致由三部分组成,标题,时间,和链接。打开爬虫的网页 缺个链接,... 查看详情

分析一套源代码的代码规范和风格并讨论如何改进优化代码(代码片段)

...分析、金融相关知识。而在网络爬虫与语义分析这方面,python的案例特别多。所以我在github找了一份python的源代码,项目名叫Financial_Analysis。看代码前分析前我们可以查看项目目录下的README.md,在项目根目录下的README.md中会对本... 查看详情

一次groupby+orderby性能优化分析(代码片段)

一次groupby+orderby性能优化分析最近通过一个日志表做排行的时候发现特别卡,最后问题得到了解决,梳理一些索引和MySQL执行过程的经验,但是最后还是有5个谜题没解开,希望大家帮忙解答下。主要包含如下知识点用数据说话证... 查看详情

爬虫数据分析的前景(代码片段)

...据挖掘,人工智能,大数据这些才可以数据分析就要使用Python,pandas库,就要使用画图工具,就要出报告,所以,爬虫下来进行数据分析还是有前景的,这是提供数据报告服务的,非常像情报收集和分析的工作爬虫下来建立仓库... 查看详情

部署awstats日志分析系统与优化(附安装包)(代码片段)

介绍  AWStats是使用Perl语言开发的一款开源日志分析系统,可以分析apache,samba,vsftpd,iis等服务的日志信息,结合crond等计划任务,可以对不断增长的日志内容定期进行分析。  它可以帮助我们直观的图形化的,图... 查看详情

python爬虫实战,scrapy实战,抓取并分析天气数据(代码片段)

前言利用Python“简单地”抓取并分析一下天气数据。补充一下之前数据可视化的空白。开发工具**Python版本:3.6.4相关模块:PIL模块;requests模块;pyecharts模块;以及一些Python自带的模块。环境搭建同Python简单分析微信好友。主要... 查看详情

scrapy框架的日志等级和请求传参,优化效率(代码片段)

目录scrapy框架的日志等级和请求传参,优化效率Scrapy的日志等级请求传参如何提高scripy的爬取效率scrapy框架的日志等级和请求传参,优化效率Scrapy的日志等级在使用scrapycrawlspiderFileName运行程序时,在终端里打印输出的就是scrapy的日... 查看详情

android性能优化内存优化分析gc日志(代码片段)

...#xff0c;可以看出来虚拟机的内存情况,这为我们做内存优化提供了另外一个可参考的依据,要尽量减少stoptheworld类型的GC。本文介绍如何查看GC日志,先做到看懂GC日志。Dalvik日志消息在Dalvik虚拟机中,主要是4.x系统 查看详情

android性能优化内存优化分析gc日志(代码片段)

...#xff0c;可以看出来虚拟机的内存情况,这为我们做内存优化提供了另外一个可参考的依据,要尽量减少stoptheworld类型的GC。本文介绍如何查看GC日志,先做到看懂GC日志。Dalvik日志消息在Dalvik虚拟机中,主要是4.x系统 查看详情

linux脚本练习之script084-nginx日志分析之统计爬虫抓取404的次数(代码片段)

script084题目注:题目来源于SHELL27nginx日志分析5-统计爬虫抓取404的次数。假设nginx的日志我们存储在nowcoder.txt里,格式如下:192.168.1.20--[21/Apr/2020:14:12:49+0800]"GET/1/index.phpHTTP/1.1"301490"-"& 查看详情

linux脚本练习之script084-nginx日志分析之统计爬虫抓取404的次数(代码片段)

script084题目注:题目来源于SHELL27nginx日志分析5-统计爬虫抓取404的次数。假设nginx的日志我们存储在nowcoder.txt里,格式如下:192.168.1.20--[21/Apr/2020:14:12:49+0800]"GET/1/index.phpHTTP/1.1"301490"-"& 查看详情

python爬虫从入门到放弃,含案例分析,超详细讲解(代码片段)

Python爬虫1、认识爬虫1.1、概述网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者)按照一定规律,自动地抓取万维网信息的程序或者脚本。1.2、应用场景爬取网页优秀的... 查看详情

爬虫数据分析的前景(代码片段)

...据挖掘,人工智能,大数据这些才可以数据分析就要使用Python,pandas库,就要使用画图工具,就要出报告,所以,爬虫下来进行数据分析还是有前景的,这是提供数据报告服务的,非常像情报收集和分析的工作爬虫下来建立仓库... 查看详情

爬虫的日志(代码片段)

1.为什么要使用添加日志功能能够方便的对程序进行调试能够记录程序的运行状态,包括错误2.日志模块简单使用日志的等级importlogging#日志的五个等级,等级依次递增#默认是WARNING等级logging.DEBUGlogging.INFOlogging.WARNINGlogging.ERRORloggi... 查看详情

redis技术专区「优化案例」谈谈使用redis慢查询日志以及redis慢查询分析指南(代码片段)

...际工作中,进行分析Redis的性能运行状况以及对应的优化Redis性能的佐证和指标因素。在我们5.0左右的版本中Redis使用单线程架构和I/O多路复用模型来实现高性能的内存数据服务。接下来主要分析Redis单线程命令处理机制,... 查看详情

python小课堂专栏python小课堂33-初识原生爬虫优化

python小课堂33-初识原生爬虫优化前言上周写的爬虫代码分析思路,没多少人看丫…果然还是代码的讲解比较枯燥无聊吧…没看的可以回顾一下啦:​​python小课堂32-初识原生爬虫(二)​​本篇文章写完会将代码放在github上,想... 查看详情

python大作业——爬虫+可视化+数据分析+数据库(可视化篇)(代码片段)

相关链接Python大作业——爬虫+可视化+数据分析+数据库(简介篇)Python大作业——爬虫+可视化+数据分析+数据库(爬虫篇)Python大作业——爬虫+可视化+数据分析+数据库(数据分析... 查看详情

python网络爬虫课程设计(代码片段)

...题式网络爬虫设计方案(10分)1.主题式网络爬虫名称《Python爬虫对站长之家网站分类信息网站排行榜的爬取及分析》2.主题式网络爬虫爬取的内容与数据特征分析爬取内容:各类网站的网 查看详情