zoukankan      html  css  js  c++  java
  • python Beautiful Soup 抓取解析网页

    Beautiful Soup is a Python library designed for quick turnaround projects like screen-scraping.总之就是一个解析xml和html之类的库,用着还算顺手。

    官网地址:http://www.crummy.com/software/BeautifulSoup/

    下面来介绍下使用python和Beautiful Soup 抓取一个网页上的PM2.5数据。

    PM2.5 数据的网站:http://www.pm25.com/city/wuhan.html

    这个网站上有相应的PM2.5数据,他们在几个地方布置的有监测器,大约每隔一个小时更新一次(有的时候,仪器的数据会丢失)。我们要抓取的数据就是几个监测点的一些空气质量指标。

     1 def getPM25():
     2     url = "http://www.pm25.com/city/wuhan.html"
     3 
     4     headers = {
     5             "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
     6             "Accept-Language":"zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3",
     7             "Connection":"keep-alive",
     8             "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0",
     9         }
    10     try:
    11         req = urllib2.Request(url,headers=headers)
    12         response =  urllib2.urlopen(req)
    13         content =  response.read()
    14         response.close()
    15         pm = BSoup(content,from_encoding="utf-8")
    16         logging.info(pm.select(".citydata_updatetime")[0].get_text() + u" ")
    17         with open('pm2dot5.txt','a') as f:
    18             print>>f, pm.select(".citydata_updatetime")[0].get_text()
    19             for locate in pm.select(".pj_area_data ul:nth-of-type(1) li"):
    20                 print>>f, locate.select(".pjadt_location")[0].get_text().rjust(15),"	",
    21                           locate.select(".pjadt_aqi")[0].get_text().rjust(15),"	",
    22                           locate.select(".pjadt_quality")[0].get_text().rjust(15),"	",
    23                           locate.select(".pjadt_wuranwu")[0].get_text().rjust(15),"	",
    24                           locate.select(".pjadt_pm25")[0].get_text().rjust(15),"	",
    25                           locate.select(".pjadt_pm10")[0].get_text().rjust(15)
    26             print>>f, "
    
    
    "
    27         return 0
    28     except Exception,e:
    29         logging.error(e)
    30         return 1

    主要使用python的库 urllib2

    • 构造发送的headers,伪装成火狐浏览器
    • 用上述数据构建一个请求,然后打开这个网络请求
    • 调用 response.read() 即可获取html的内容

    提取标签内容

    下面就是使用Beautiful Soup来解析html内容,提取标签里的数值。具体函数还是要参见官方文档。

    这里主要使用了select方法和get_text方法。

    select方法可以根据标签名(tag,比如 a,li,body)或者css类或者id来选择元素。

    get_text方法可以获取对应的文本,比如"<h1>hello</h1>",就可以获得 "hello"

    具体的元素类,需要借助浏览器的审查元素功能来查看

    写入文本:

      主要使用了python的 with语法,with能够确保打开的文件发生异常时一定会被关闭。同时使用了一个流重定向的小技巧,

    print >> f,"hello"   f为打开的文件流,这句话的意思是将print打印的东西重定向到文件中。

    日志记录:

    由于这个程序要在后台跑很久,所以还是最好记录下出错的信息,方便调试。使用的python自带的logging模块。

     1 logging.basicConfig(level=logging.DEBUG,
     2                 format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
     3                 datefmt='%a, %d %b %Y %H:%M:%S',
     4                 filename='debug.log',
     5                 filemode='w')
     6     console = logging.StreamHandler()
     7     console.setLevel(logging.INFO)
     8     formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
     9     console.setFormatter(formatter)
    10     logging.getLogger('').addHandler(console)
    11     Rthandler = RotatingFileHandler('debug.log', maxBytes=1*1024*1024,backupCount=5)
    12     Rthandler.setLevel(logging.INFO)
    13     formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
    14     Rthandler.setFormatter(formatter)
    15     logging.getLogger('').addHandler(Rthandler)

    其中包括了一些,设置日志的格式,以及日志文件的最大大小。

    定时运行:

    定时运行,可以每天抓取指定时间的PM2.5数据,结合卫星过境时间来做进一步的分析。定时使用的也是python自带的sched模块。

     1 def run():
     2     while True:
     3         s = sched.scheduler(time.time, time.sleep)
     4         s.enterabs(each_day_time(9,50,30), 1, getPM25, ())
     5         try:
     6             s.run()
     7         except:
     8             s.run()
     9         time.sleep(60*60)
    10         logging.info("second run")
    11         while getPM25():
    12             pass
    13         time.sleep( 60*60)
    14         logging.info("third run")
    15         while getPM25():
    16             pass
    17         time.sleep(60*60)
    18         logging.info("fourth run")
    19         while getPM25():
    20             pass
    21         logging.info(u"
    
    等待下次运行...")

    其中each_day_time是一个获取指定时间的函数

    1 def each_day_time(hour,minute,sec):
    2         today = datetime.datetime.today()
    3         today = datetime.datetime(today.year,today.month,today.day,hour,minute,sec)
    4         tomorrow = today + datetime.timedelta(days=1)
    5         xtime = time.mktime(tomorrow.timetuple())
    6         #xtime = time.mktime(today.timetuple())
    7         return xtime

    另外,如果指定的时间已经过去,他就会一直运行下去。

    完整代码下载(python 2.7): https://files.cnblogs.com/files/pasion-forever/pm2-5.v1.rar

     另:直接双击pyw文件,会调用pythonw.exe 来执行,如果没有GUI,默认的就是后台运行。

     抓取的结果:

      

  • 相关阅读:
    Spring AOP 注解开发
    AOP的专业术语
    Java自定义注解的实现和应用
    Spring 声明式事务管理
    另一种线程安全机制:在事务管理中起到巨大作用的 ThreadLocal
    MySQL的二级索引
    数据库的范式化和反范式化
    MySQL为表字段添加索引
    mysql索引(二)----如何高效使用索引
    Alexnet网络
  • 原文地址:https://www.cnblogs.com/pasion-forever/p/4329990.html
Copyright © 2011-2022 走看看