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),"\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"

具體的元素類,需要借助瀏覽器的審查元素功能來查看

寫入文本:

  主要使用了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,默認的就是后台運行。

 抓取的結果:

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM