设为首页 收藏本站
查看: 1199|回复: 0

[经验分享] python Beautiful Soup 抓取解析网页

[复制链接]

尚未签到

发表于 2015-12-1 15:27:56 | 显示全部楼层 |阅读模式
  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数据,他们在几个地方布置的有监测器,大约每隔一个小时更新一次(有的时候,仪器的数据会丢失)。我们要抓取的数据就是几个监测点的一些空气质量指标。
DSC0000.jpg
  
  



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),"\t",\
21                           locate.select(".pjadt_aqi")[0].get_text().rjust(15),"\t",\
22                           locate.select(".pjadt_quality")[0].get_text().rjust(15),"\t",\
23                           locate.select(".pjadt_wuranwu")[0].get_text().rjust(15),"\t",\
24                           locate.select(".pjadt_pm25")[0].get_text().rjust(15),"\t",\
25                           locate.select(".pjadt_pm10")[0].get_text().rjust(15)
26             print>>f, "\n\n\n"
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"
  具体的元素类,需要借助浏览器的审查元素功能来查看
DSC0001.jpg
  写入文本:
    主要使用了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"\n\n等待下次运行...")
  
  其中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): http://files.cnblogs.com/files/pasion-forever/pm2-5.v1.rar
  另:直接双击pyw文件,会调用pythonw.exe 来执行,如果没有GUI,默认的就是后台运行。
  抓取的结果:
DSC0002.jpg
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-145998-1-1.html 上篇帖子: python 安装influxdb-python 下篇帖子: 使用python做简单的接口性能测试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表