澳门新葡8455手机版-澳门新葡8455最新网站

您的位置:澳门新葡8455手机版 > 新闻资讯 > 你又不能查看日志,涉及的内容包括

你又不能查看日志,涉及的内容包括

2019-10-05 10:19

咱俩在写webapp大概移动端网页须要安置到app时候,特别是在应用程式内置的webView上加载大家的页面,想要查看手提式有线电电话机浏览器音讯是不行不方便的事,当出现难题的时候,你又不可能查看日志,日常会再而三本地质衡量试意况,然后在alert来打字与印刷日志,然后叁次三遍的恒久bug,修改代码。使用eruda之后认为爽爆了,消除了这么些难题,这些工具就想计算机端的devtools,能够查阅日志,互联网,页面,Resources等

本次为大家带来的是抓取爱问知识人的主题素材并将难题和答案保存到数据库的不二秘籍,涉及的源委包罗:

多页面使用

在种种页面

<script type="text/javascript" src="http://www.jingklong.com/uploads/allimg/191005/1019464J0-0.jpg"></script><script>eruda.init();</script>
  • Urllib的用法及特别管理
  • Beautiful Soup的轻便利用
  • MySQLdb的根基用法
  • 正则表明式的简便利用

单页应用

npm install --save-dev eruda

;(function () { if (!/mdebug=true/.test(window.location.href)) return; var script = document.createElement script.src = "http://www.jingklong.com/uploads/allimg/191005/1019464J0-0.jpg" script.async = true document.getElementsByTagName[0].appendChild script.onload = function () { eruda.init

咱俩在档次的输入引用那些文件就能够

小编们只要求在地点栏扩展mdebug=true就可以,是否很实惠?

条件布置

在那前面,大家需求先配备一下遇到,笔者的Python的版本为2.7,须求额外安装的库有三个,多个是Beautiful Soup,二个是MySQLdb,在这里附上四个库的下载地址,

Beautiful Soup     MySQLdb

世家能够下载之后通过如下命令安装

​python setup.py install

条件布置好之后,大家便足以高兴地撸爬虫了

框架思路

首先我们无论找一个分拣地址,外国语学习 – 爱问知识人,张开现在能够看出一多元的标题列表。

大家在这几个页面要求获得的事物有:

总的页码数,每一页的保反常链接。

接下去大家要求遍历全数的难点,来抓取每一个端详页面,提取难点,难题内容,回答者,回答时间,回答内容。

末段,大家要求把那几个内容存款和储蓄到数据库中。

要点简析

实质上海大学部分剧情相信大家会了前方的内容,这里的爬虫思路已经融汇贯通了,这里就说一下部分恢宏的作用

1.日志输出

日记输出,大家要出口时间和爬取的情况,比方像下边那样:

[2015-08-10 03:05:20] 113011 号难点存在其余答案 小编个人以为应当是车厘子沟相当美丽的

[2015-08-10 03:05:20] 保存到数据库,此主题材料的ID为 113011

[2015-08-10 03:05:20] 当前爬取第 2 的原委,发现多少个主题材料百度有一个地点,花儿带着香味,水儿流淌奔腾是什么样意思 多多支持哦 回答数量 1

[2015-08-10 03:05:19] 保存到数据库,此难点的ID为 113010

由此,大家须求引进时间函数,然后写三个拿走当前光阴的函数

​import time

#获取当前时间
def getCurrentTime(self):
    return time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time()))

#获取当前时间
def getCurrentDate(self):
    return time.strftime('%Y-%m-%d',time.localtime(time.time()))

​

以上分别是获得带具体时刻和收获日期的函数,在输出时,大家能够在输出语句的先头调用那函数就可以。

下一场大家要求将缓冲区设置输出到log中,在前后相继的最前头加上这两句就可以

​f_handler=open('out.log', 'w') 
sys.stdout=f_handler

​

诸有此类,全体的print语句输出的从头到尾的经过就能保留到out.log文件中了。

2.页码保存

爬虫爬取进程中或然出现五颜六色的谬误,那样会促成爬虫的间歇,假诺大家再一次运营爬虫,那么就能产生爬虫从头初叶运行了,那样分明是不客观的。所以,我们必要把当下爬取的页面保存下去,比方可以保存到文本中,若是爬虫中断了,重国民党的新生活运动行爬虫,读取文本文件的开始和结果,接着爬取就可以。

世家可以稍微参照他事他说加以考察一下函数的兑现:

​

    #主函数
    def main(self):
        f_handler=open('out.log', 'w') 
        sys.stdout=f_handler
        page = open('page.txt', 'r')
        content = page.readline()
        start_page = int(content.strip()) - 1
        page.close()     
        print self.getCurrentTime(),"开始页码",start_page
        print self.getCurrentTime(),"爬虫正在启动,开始爬取爱问知识人问题"
        self.total_num = self.getTotalPageNum()
        print self.getCurrentTime(),"获取到目录页面个数",self.total_num,"个"
        if not start_page:
            start_page = self.total_num
        for x in range(1,start_page):
            print self.getCurrentTime(),"正在抓取第",start_page-x+1,"个页面"
            try:
                self.getQuestions(start_page-x+1)
            except urllib2.URLError, e:
                if hasattr(e, "reason"):
                    print self.getCurrentTime(),"某总页面内抓取或提取失败,错误原因", e.reason
            except Exception,e:  
                print self.getCurrentTime(),"某总页面内抓取或提取失败,错误原因:",e
            if start_page-x+1 < start_page:
                f=open('page.txt','w')
                f.write(str(start_page-x+1))
                print self.getCurrentTime(),"写入新页码",start_page-x+1
                f.close()

​

如此这般,不管大家爬虫中途遭逢怎么样错误,老妈也不会顾虑了

3.页面甩卖

页面管理进程中,我们大概碰到多姿多彩奇葩的HTML代码,和上一节同样,大家沿用三个页面管理类就可以。

​

import re

#处理页面标签类
class Tool:

    #将超链接广告剔除
    removeADLink = re.compile('<div class="link_layer.*?</div>')
    #去除img标签,1-7位空格,&nbsp;
    removeImg = re.compile('<img.*?>| {1,7}|&nbsp;')
    #删除超链接标签
    removeAddr = re.compile('<a.*?>|</a>')
    #把换行的标签换为n
    replaceLine = re.compile('<tr>|<div>|</div>|</p>')
    #将表格制表<td>替换为t
    replaceTD= re.compile('<td>')
    #将换行符或双换行符替换为n
    replaceBR = re.compile('<br><br>|<br>')
    #将其余标签剔除
    removeExtraTag = re.compile('<.*?>')
    #将多行空行删除
    removeNoneLine = re.compile('n+')

    def replace(self,x):
        x = re.sub(self.removeADLink,"",x)
        x = re.sub(self.removeImg,"",x)
        x = re.sub(self.removeAddr,"",x)
        x = re.sub(self.replaceLine,"n",x)
        x = re.sub(self.replaceTD,"t",x)
        x = re.sub(self.replaceBR,"n",x)
        x = re.sub(self.removeExtraTag,"",x)
        x = re.sub(self.removeNoneLine,"n",x)
        #strip()将前后多余内容删除
        return x.strip()

​

咱俩得以用一段含有HTML代码的文字,经过调用replace方法之后,各类冗余的HTML代码就能够管理好了。

比如我们如此一段代码:

​

<article class="article-content">
<h2>前言</h2>
<p>最近发现MySQL服务隔三差五就会挂掉,导致我的网站和爬虫都无法正常运作。自己的网站是基于MySQL,在做爬虫存取一些资料的时候也是基于MySQL,数据量一大了,MySQL它就有点受不了了,时不时会崩掉,虽然我自己有网站监控和邮件通知,但是好多时候还是需要我来手动连接我的服务器重新启动一下我的MySQL,这样简直太不友好了,所以,我就觉定自己写个脚本,定时监控它,如果发现它挂掉了就重启它。</p>
<p>好了,闲言碎语不多讲,开始我们的配置之旅。</p>
<p>运行环境:<strong>Ubuntu Linux 14.04</strong></p>
<h2>编写Shell脚本</h2>
<p>首先,我们要编写一个shell脚本,脚本主要执行的逻辑如下:</p>
<p>显示mysqld进程状态,如果判断进程未在运行,那么输出日志到文件,然后启动mysql服务,如果进程在运行,那么不执行任何操作,可以选择性输出监测结果。</p>
<p>可能大家对于shell脚本比较陌生,在这里推荐官方的shell脚本文档来参考一下</p>
<p><a href="http://wiki.ubuntu.org.cn/Shell%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80" data-original-title="" title="">Ubuntu Shell 编程基础</a></p>
<p>shell脚本的后缀为sh,在任何位置新建一个脚本文件,我选择在 /etc/mysql 目录下新建一个 listen.sh 文件。</p>
<p>执行如下命令:</p>

​

透过管理后便会化为如下的样板:

​

前言
最近发现MySQL服务隔三差五就会挂掉,导致我的网站和爬虫都无法正常运作。自己的网站是基于MySQL,在做爬虫存取一些资料的时候也是基于MySQL,数据量一大了,MySQL它就有点受不了了,时不时会崩掉,虽然我自己有网站监控和邮件通知,但是好多时候还是需要我来手动连接我的服务器重新启动一下我的MySQL,这样简直太不友好了,所以,我就觉定自己写个脚本,定时监控它,如果发现它挂掉了就重启它。
好了,闲言碎语不多讲,开始我们的配置之旅。
运行环境:UbuntuLinux14.04
编写Shell脚本
首先,我们要编写一个shell脚本,脚本主要执行的逻辑如下:
显示mysqld进程状态,如果判断进程未在运行,那么输出日志到文件,然后启动mysql服务,如果进程在运行,那么不执行任何操作,可以选择性输出监测结果。
可能大家对于shell脚本比较陌生,在这里推荐官方的shell脚本文档来参考一下
UbuntuShell编程基础
shell脚本的后缀为sh,在任何位置新建一个脚本文件,我选择在/etc/mysql目录下新建一个listen.sh文件。
执行如下命令:

​

透过地点的拍卖,全部乱乱的代码都会被管理好了。

4.保留到数据库

在这里,大家想完毕贰个通用的点子,就是把仓储的多个个内容形成字典的花样,然后施行插入语句的时候,自动营造对应的sql语句,插入数据。

譬喻大家组织如下的字典:

​#构造最佳答案的字典
good_ans_dict = {
        "text": good_ans[0],
        "answerer": good_ans[1],
        "date": good_ans[2],
        "is_good": str(good_ans[3]),
        "question_id": str(insert_id)
        }

​

布局sql语句并插入到数据库的法子如下:

​

#插入数据
    def insertData(self, table, my_dict):
         try:
             self.db.set_character_set('utf8')
             cols = ', '.join(my_dict.keys())
             values = '"," '.join(my_dict.values())
             sql = "INSERT INTO %s (%s) VALUES (%s)" % (table, cols, '"'+values+'"')
             try:
                 result = self.cur.execute(sql)
                 insert_id = self.db.insert_id()
                 self.db.commit()
                 #判断是否执行成功
                 if result:
                     return insert_id
                 else:
                     return 0
             except MySQLdb.Error,e:
                 #发生错误时回滚
                 self.db.rollback()
                 #主键唯一,无法插入
                 if "key 'PRIMARY'" in e.args[1]:
                     print self.getCurrentTime(),"数据已存在,未插入数据"
                 else:
                     print self.getCurrentTime(),"插入数据失败,原因 %d: %s" % (e.args[0], e.args[1])
         except MySQLdb.Error,e:
             print self.getCurrentTime(),"数据库错误,原因%d: %s" % (e.args[0], e.args[1])

​

此地大家只需求传入那多少个字典,便会营造出对应字典键值和键名的sql语句,完结插入。

5.PHP读取日志

咱俩将运营结果输出到了日志里,那么怎么查看日志呢?异常的粗略,在这边提供三种艺术

方法一:

PHP倒序输出全数日志内容

​

<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="refresh" content = "5"> 
    </head>
    <body>
        <?php
            $fp = file("out.log");
            if ($fp) {
                for($i = count($fp) - 1;$i >= 0; $i --) 
                echo $fp[$i]."<br>";
            }
        ?>
    </body>
</html>

​

此方式能够看看全部的输入日志,可是一旦日志太大了,那么就能够报开支内部存款和储蓄器太大,不可能输出。为此大家就有了第两种格局,利用linux命令,输出后十行内容。

方法二:

​

<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="refresh" content = "5"> 
    </head>
    <body>
        <?php 
            $ph = popen('tail -n 100 out.log','r');
            while($r = fgets($ph)){
                echo $r."<br>";
            }
            pclose($ph);
        ?>
    </body>
</html>

​

地点二种格局都以5秒刷新三回网页来查阅最新的日志。

源代码放送

好了,闲言碎语相当少讲,直接上源码了

​
spider.py

​

​

spider.py


# -*- coding:utf-8 -*-

import urllib
import urllib2
import re
import time
import types
import page
import mysql
import sys
from bs4 import BeautifulSoup

class Spider:

    #初始化
    def __init__(self):
        self.page_num = 1
        self.total_num = None
        self.page_spider = page.Page()
        self.mysql = mysql.Mysql()

    #获取当前时间
    def getCurrentTime(self):
        return time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time()))

    #获取当前时间
    def getCurrentDate(self):
        return time.strftime('%Y-%m-%d',time.localtime(time.time()))

    #通过网页的页码数来构建网页的URL
    def getPageURLByNum(self, page_num):
        page_url = "http://iask.sina.com.cn/c/978-all-" + str(page_num) + ".html"
        return page_url


    #通过传入网页页码来获取网页的HTML
    def getPageByNum(self, page_num):
        request = urllib2.Request(self.getPageURLByNum(page_num))
        try:
            response = urllib2.urlopen(request)
        except urllib2.URLError, e:
            if hasattr(e, "code"):
                print self.getCurrentTime(),"获取页面失败,错误代号", e.code
                return None
            if hasattr(e, "reason"):
                print self.getCurrentTime(),"获取页面失败,原因", e.reason
                return None
        else:
            page =  response.read().decode("utf-8")
            return page

    #获取所有的页码数
    def getTotalPageNum(self):
        print self.getCurrentTime(),"正在获取目录页面个数,请稍候"
        page = self.getPageByNum(1)
        #匹配所有的页码数,u4e0bu4e00u9875是下一页的UTF8编码
        pattern = re.compile(u'.*?(.*?)</a>s*<a.*?u4e0bu4e00u9875</a>', re.S)
        match = re.search(pattern, page)
        if match:
            return match.group(1)
        else:
            print self.getCurrentTime(),"获取总页码失败"

    #分析问题的代码,得到问题的提问者,问题内容,回答个数,提问时间
    def getQuestionInfo(self, question):
        if not type(question) is types.StringType:
            question = str(question)
        #print question
        pattern = re.compile(u'.*?<img.*?alt="(.*?)".*?.*?<a href="(.*?)".*?>(.*?)</a>.*?answer_num.*?>(d*).*?.*?answer_time.*?>(.*?)', re.S)
        match = re.search(pattern, question)
        if match:
            #获得提问者
            author = match.group(1)
            #问题链接
            href = match.group(2)
            #问题详情
            text = match.group(3)
            #回答个数
            ans_num = match.group(4)
            #回答时间
            time = match.group(5)
            time_pattern = re.compile('d{4}-d{2}-d{2}', re.S)
            time_match = re.search(time_pattern, time)
            if not time_match:
                time = self.getCurrentDate()
            return [author, href, text, ans_num, time]
        else:
            return None

    #获取全部问题
    def getQuestions(self, page_num):
        #获得目录页面的HTML
        page = self.getPageByNum(page_num)
        soup = BeautifulSoup(page)
        #分析获得所有问题
        questions = soup.select("div.question_list ul li")
        #遍历每一个问题
        for question in questions:
            #获得问题的详情
            info = self.getQuestionInfo(question)
            if info:
                #得到问题的URL
                url = "http://iask.sina.com.cn/" + info[1]
                #通过URL来获取问题的最佳答案和其他答案
                ans = self.page_spider.getAnswer(url)
                print self.getCurrentTime(),"当前爬取第",page_num,"的内容,发现一个问题",info[2],"回答数量",info[3]
                #构造问题的字典,插入问题
                ques_dict = {
                            "text": info[2],
                            "questioner": info[0],
                            "date": info[4],
                            "ans_num": info[3],
                            "url": url
                            }
                #获得插入的问题的自增ID 
                insert_id = self.mysql.insertData("iask_questions",ques_dict)
                #得到最佳答案
                good_ans = ans[0]
                print self.getCurrentTime(),"保存到数据库,此问题的ID为",insert_id
                #如果存在最佳答案,那么就插入
                if good_ans:
                    print self.getCurrentTime(),insert_id,"号问题存在最佳答案",good_ans[0]
                    #构造最佳答案的字典
                    good_ans_dict = {
                            "text": good_ans[0],
                            "answerer": good_ans[1],
                            "date": good_ans[2],
                            "is_good": str(good_ans[3]),
                            "question_id": str(insert_id)
                            }
                    #插入最佳答案
                    if self.mysql.insertData("iask_answers",good_ans_dict):
                        print self.getCurrentTime(),"保存最佳答案成功"
                    else:
                        print self.getCurrentTime(),"保存最佳答案失败"
                #获得其他答案
                other_anses = ans[1]
                #遍历每一个其他答案
                for other_ans in other_anses:
                    #如果答案存在
                    if other_ans:
                        print self.getCurrentTime(),insert_id,"号问题存在其他答案",other_ans[0]
                        #构造其他答案的字典
                        other_ans_dict = {
                                "text": other_ans[0],
                                "answerer": other_ans[1],
                                "date": other_ans[2],
                                "is_good": str(other_ans[3]),
                                "question_id": str(insert_id)
                                }
                        #插入这个答案
                        if self.mysql.insertData("iask_answers",other_ans_dict):
                            print self.getCurrentTime(),"保存其他答案成功"
                        else:
                            print self.getCurrentTime(),"保存其他答案失败"

    #主函数
    def main(self):
        f_handler=open('out.log', 'w') 
        sys.stdout=f_handler
        page = open('page.txt', 'r')
        content = page.readline()
        start_page = int(content.strip()) - 1
        page.close()     
        print self.getCurrentTime(),"开始页码",start_page
        print self.getCurrentTime(),"爬虫正在启动,开始爬取爱问知识人问题"
        self.total_num = self.getTotalPageNum()
        print self.getCurrentTime(),"获取到目录页面个数",self.total_num,"个"
        if not start_page:
            start_page = self.total_num
        for x in range(1,start_page):
            print self.getCurrentTime(),"正在抓取第",start_page-x+1,"个页面"
            try:
                self.getQuestions(start_page-x+1)
            except urllib2.URLError, e:
                if hasattr(e, "reason"):
                    print self.getCurrentTime(),"某总页面内抓取或提取失败,错误原因", e.reason
            except Exception,e:  
                print self.getCurrentTime(),"某总页面内抓取或提取失败,错误原因:",e
            if start_page-x+1 < start_page:
                f=open('page.txt','w')
                f.write(str(start_page-x+1))
                print self.getCurrentTime(),"写入新页码",start_page-x+1
                f.close()

spider = Spider()
spider.main()       

page = Page()
page.getAnswer(None)

# -*- coding:utf-8 -*-
import urllib
import urllib2
import re
import time
import types 
import tool
from bs4 import BeautifulSoup

#抓取分析某一问题和答案
class Page:

    def __init__(self):
        self.tool = tool.Tool()

    #获取当前时间
    def getCurrentDate(self):
        return time.strftime('%Y-%m-%d',time.localtime(time.time()))

    #获取当前时间
    def getCurrentTime(self):
        return time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time()))

    #通过页面的URL来获取页面的代码
    def getPageByURL(self, url):
        try:
            request = urllib2.Request(url)
            response = urllib2.urlopen(request)
            return response.read().decode("utf-8") 
        except urllib2.URLError, e:

tool.py



#-*- coding:utf-8 -*-
import re

#处理页面标签类
class Tool:

    #将超链接广告剔除
    removeADLink = re.compile('<div class="link_layer.*?</div>')
    #去除img标签,1-7位空格,&nbsp;
    removeImg = re.compile('<img.*?>| {1,7}|&nbsp;')
    #删除超链接标签
    removeAddr = re.compile('<a.*?>|</a>')
    #把换行的标签换为n
    replaceLine = re.compile('<tr>|<div>|</div>|</p>')
    #将表格制表<td>替换为t
    replaceTD= re.compile('<td>')
    #将换行符或双换行符替换为n
    replaceBR = re.compile('<br><br>|<br>')
    #将其余标签剔除
    removeExtraTag = re.compile('<.*?>')

mysql.py


# -*- coding:utf-8 -*-


import MySQLdb
import time

class Mysql:

    #获取当前时间
    def getCurrentTime(self):
        return time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time()))

    #数据库初始化
    def __init__(self):
        try:
            self.db = MySQLdb.connect('ip','username','password','db_name')
            self.cur = self.db.cursor()
        except MySQLdb.Error,e:
             print self.getCurrentTime(),"连接数据库错误,原因%d: %s" % (e.args[0], e.args[1])

    #插入数据
    def insertData(self, table, my_dict):
         try:
             self.db.set_character_set('utf8')
             cols = ', '.join(my_dict.keys())
             values = '"," '.join(my_dict.values())
             sql = "INSERT INTO %s (%s) VALUES (%s)" % (table, cols, '"'+values+'"')
             try:
                 result = self.cur.execute(sql)
                 insert_id = self.db.insert_id()
                 self.db.commit()
                 #判断是否执行成功
                 if result:
                     return insert_id
                 else:
                     return 0
             except MySQLdb.Error,e:
                 #发生错误时回滚
                 self.db.rollback()
                 #主键唯一,无法插入
                 if "key 'PRIMARY'" in e.args[1]:
                     print self.getCurrentTime(),"数据已存在,未插入数据"
                 else:
                     print self.getCurrentTime(),"插入数据失败,原因 %d: %s" % (e.args[0], e.args[1])
         except MySQLdb.Error,e:
             print self.getCurrentTime(),"数据库错误,原因%d: %s" % (e.args[0], e.args[1])
数据库建表SQL如下:

PgSQL

CREATE TABLE IF NOT EXISTS `iask_answers` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `text` text NOT NULL COMMENT '回答内容',
  `question_id` int(18) NOT NULL COMMENT '问题ID',
  `answerer` varchar(255) NOT NULL COMMENT '回答者',
  `date` varchar(255) NOT NULL COMMENT '回答时间',
  `is_good` int(11) NOT NULL COMMENT '是否是最佳答案',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `iask_questions` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '问题ID',
  `text` text NOT NULL COMMENT '问题内容',
  `questioner` varchar(255) NOT NULL COMMENT '提问者',
  `date` date NOT NULL COMMENT '提问时间',
  `ans_num` int(11) NOT NULL COMMENT '回答数量',
  `url` varchar(255) NOT NULL COMMENT '问题链接',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
运行的时候执行如下命令即可

nohup python spider.py &

​

运行结果查看

大家把PHP文件和log文件放在同样目录下,运营PHP文件,便得以看见如下的剧情:

图片 1

本文由澳门新葡8455手机版发布于新闻资讯,转载请注明出处:你又不能查看日志,涉及的内容包括

关键词:

  • 上一篇:没有了
  • 下一篇:没有了