1. 程式人生 > >從人人網獲取全國中學資訊(省市縣)

從人人網獲取全國中學資訊(省市縣)

最近有個專案需要用到全國中學的資訊,自己整理肯定事很難可行了,在網上看到這一片文章:用HttpClient抓取人人網高校資料庫(http://www.iteye.com/topic/826988),就想能不能從人人網上把這部分資訊搞下來。下面是實現步驟:

1 首先firefox安裝httpfox外掛,用來監控http請求

2 登入人人網,修改個人基本資訊,點選修改學校資訊

3 開啟httpfox,點選start,開始監控http資訊,如下圖



4 點選學校資訊的高中,此時會彈出學校選擇對話方塊,然後注意觀察http請求





注意看選中的那一行,就是從伺服器傳回來的學校資料,content裡面是伺服器返回的資料,一段標準的html程式碼,拷貝連結到瀏覽器,出現如下介面,可以得出一個結論,這部分資源資訊,人人也沒有加session驗證,省去了不少麻煩。



多點選幾個其他的省看一下:


發現每個省請求的連結都不同,分析可以知道,每個市對應於一個html檔案,省和市這兩級的資料經過分析可以在cityArray.js這個檔案中找到,檔案的結構如下所示:

var _city_1=["110101:\u4e1c\u57ce\u533a","110102:\u897f\u57ce\u533a","110103:\u5d07\u6587\u533a","110104:\u5ba3\u6b66\u533a","110105:\u671d\u9633\u533a","110106:\u4e30\u53f0\u533a","110107:\u77f3\u666f\u5c71\u533a","110108:\u6d77\u6dc0\u533a","110109:\u95e8\u5934\u6c9f\u533a","110111:\u623f\u5c71\u533a","110112:\u901a\u5dde\u533a","110113:\u987a\u4e49\u533a","110114:\u660c\u5e73\u533a","110115:\u5927\u5174\u533a","110116:\u6000\u67d4\u533a","110117:\u5e73\u8c37\u533a","110228:\u5bc6\u4e91\u53bf","110229:\u5ef6\u5e86\u53bf"];
var _city_2=["310101:\u9ec4\u6d66\u533a","310103:\u5362\u6e7e\u533a","310104:\u5f90\u6c47\u533a","310105:\u957f\u5b81\u533a","310106:\u9759\u5b89\u533a","310107:\u666e\u9640\u533a","310108:\u95f8\u5317\u533a","310109:\u8679\u53e3\u533a","310110:\u6768\u6d66\u533a","310112:\u95f5\u884c\u533a","310113:\u5b9d\u5c71\u533a","310114:\u5609\u5b9a\u533a","310115:\u6d66\u4e1c\u65b0\u533a","310116:\u91d1\u5c71\u533a","310117:\u677e\u6c5f\u533a","310118:\u9752\u6d66\u533a","310119:\u5357\u6c47\u533a","310120:\u5949\u8d24\u533a","310230:\u5d07\u660e\u53bf"];
var _city_3=["120101:\u548c\u5e73\u533a","120102:\u6cb3\u4e1c\u533a","120103:\u6cb3\u897f\u533a","120104:\u5357\u5f00\u533a","120105:\u6cb3\u5317\u533a","120106:\u7ea2\u6865\u533a","120107:\u5858\u6cbd\u533a","120108:\u6c49\u6cbd\u533a","120109:\u5927\u6e2f\u533a","120110:\u4e1c\u4e3d\u533a","120111:\u897f\u9752\u533a","120112:\u6d25\u5357\u533a","120113:\u5317\u8fb0\u533a","120114:\u6b66\u6e05\u533a","120115:\u5b9d\u577b\u533a","120221:\u5b81\u6cb3\u53bf","120223:\u9759\u6d77\u53bf","120225:\u84df\u53bf"];
每一行代表一個省的城市資料,對中文進行了編碼,可以通過程式解碼出來看看,python中可以用下面的程式碼,解碼\u897f\u57ce格式的編碼
s="\u6cb3"
s.decode('unicode_escape')

由此檔案可以分析出全國省市兩級的結構,程式碼如下

def getProvinceData():
    content = open("/home/xiyang/workspace/school-data/cityArray.js")
    #分離出市級id和名稱
    partten = re.compile("(\d+):([\w\d\\\\]+)")
    provinceList = []
    for line in content.readlines():
        data = partten.findall(line)
        citys = []
        province = {} 
        for s in data:
            if len(s[0]) == 4:#城市
                #print s[0],s[1].decode('unicode_escape')
                citys.append({"id":s[0],"name":s[1].decode('unicode_escape')})
            
        province_id = len(data[0][0])==4 and data[0][0] or data[0][0][0:4]
    
        #只處理列表中的幾個省
        if provinceMap.has_key(int(province_id)):
            province['id'] = province_id
            province['name'] = provinceMap[int(province_id)]
            province['citys'] = citys
            provinceList.append(province)
        
    return provinceList
通過httpfox分析出來每個市對應一個html檔案,包含該市所有的縣區和學校的資料,請求的連結類似與http://support.renren.com/juniorschool/1101.html,返回的資料格式片段如下所示:
<ul id="schoolCityQuList" class="module-qulist"><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370102')">歷下區</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370103')">市中區</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370104')">槐蔭區</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370105')">天橋區</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370112')">歷城區</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370113')">長清區</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370124')">平陰縣</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370125')">濟陽縣</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370126')">商河縣</a></li><li><a href="#highschool_anchor"  onclick="SchoolComponent.tihuan('city_qu_370181')">章丘市</a></li></ul>

<ul id="city_qu_370102" style="display:none;">
<li><a onclick='if(SchoolComponent.cl_school){return SchoolComponent.cl_school(event,40019572)}' href="40019572">山師大附中</a></li>
<li><a onclick='if(SchoolComponent.cl_school){return SchoolComponent.cl_school(event,40033777)}' href="40033777">濟南二十四中</a></li>
<li><a onclick='if(SchoolComponent.cl_school){return SchoolComponent.cl_school(event,40033962)}' href="40033962">濟寧育才學校</a></li>

獲取這些資料可以使用urllib2方便的獲取

#獲得某個市級區域的學校列表,如果事直轄市,則是整個直轄市的學校
def getTownHtml(town_id):
    try:
        url = "http://support.renren.com/juniorschool/%s.html" % town_id
        print "請求網路資料:",url
        return urllib2.urlopen(url).read()
    except:
        print "網路錯誤!"
        pass

5 分析這部分資料,可以有多個思路:
  • 直接使用jquery分析html,然後使用檔案相關api儲存到檔案,這種方式分析html是比較方便的,由於chrome和firefox的檔案操作比較麻煩,沒有繼續嘗試
  • 使用正則表示式分析出資料,這種方式提取縣區還是比較簡單的,但是想要分析完整的資料還是不太好用
  • 使用html解析工具,解析html的結構,提取資料,最後選用了這一種。
在python中,有多個解析html的工具,比如HTMLParser,sgmllib,htmllib,他們都是基於事件驅動的,對於這種結構的資料還是不怎麼好用,最後選用了BeautifulSoup,分析這個資料格式小菜一碟,下面是程式碼:
#獲得某個的市級區域所有縣區的學校
def getCitySchool(content):
    soup = BeautifulSoup(content)
    
    #某個城市的中學列表
    citySchoolData = []
    #縣區的列表
    townlist = soup.findAll('a',href="#highschool_anchor")    


    for town in townlist:
        d = {}
        d['name'] = getUnicodeStr(town.string)
        d['id'] = town['onclick'][24:38]
        townSchools = []
        #獲得每個縣的中學列表
        for school in soup.find('ul',id=d['id']).findChildren('a'):
            townSchools.append(getUnicodeStr(school.string))
        d['schoollist'] = townSchools
        
        citySchoolData.append(d)
    
    return citySchoolData

上面的函式,分析html的內容,並返回某個市所有的縣區和學校的資訊, 執行之後的結果:

這樣即可根據個人的需要完成進一步的操作了。 完整的程式碼如下,
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#============================================
# Author:[email protected]
# date:2012-12-29
# description: 解析人人網全國中學數學資訊
# 思路:
# 1 首先獲取全國的省市的資料(下載cityarray.js並使用正則表示式解析)
# 2 每個市(包括直轄市)對應一個html檔案,包含了該市所有的縣區列表和學校列表,通過urllib2模組從網上下載資料
# 3 使用BeautifulSoup分析從網上抓取的資料,然後解析出資料內容
# 4 將資料存到mongodb中
#============================================
import urllib2
import re
from BeautifulSoup import BeautifulSoup
from pymongo import MongoClient

db_host = "127.0.0.1"
db_port = 27017
db_name = "openclass"

provinceMap = {
    "北京":1101,
    "上海":3101,
    "天津":1201,
    "重慶":5001,
    "黑龍江":2301,
    "吉林":2201,
    "遼寧":2101,
    "山東":3701,
    "山西":1401,
    "陝西":6101,
    "河北":1301,
    "河南":4101,
    "湖北":4201,
    "湖南":4301,
    "海南":4601,
    "江蘇":3201,
    "江西":3601,
    "廣東":4401,
    "廣西":4501,
    "雲南":5301,
    "貴州":5201,
    "四川":5101,
    "內蒙古":1501,
    "寧夏":6401,
    "甘肅":6201,
    "青海":6301,
    "西藏":5401,
    "新疆":6501,
    "安徽":3401,
    "浙江":3301,
    "福建":3501,
    "香港":8101,
}
provinceMap = dict([[v,k] for k,v in provinceMap.items()])

#解碼字串 北京
def getUnicodeStr(s):
    name = []
    for word in s.split(";"):
        try:
            name.append(unichr(int(word[2:])))
        except:
            pass    
    return "".join(name)

#獲得某個市級區域的學校列表,如果事直轄市,則是整個直轄市的學校
def getTownHtml(town_id):
    try:
        url = "http://support.renren.com/juniorschool/%s.html" % town_id
        print "請求網路資料:",url
        return urllib2.urlopen(url).read()
    except:
        print "網路錯誤!"
        pass
         
def getProvinceData():
    content = open("/home/xiyang/workspace/school-data/cityArray.js")
    #分離出市級id和名稱
    partten = re.compile("(\d+):([\w\d\\\\]+)")
    provinceList = []
    for line in content.readlines():
        data = partten.findall(line)
        citys = []
        province = {} 
        for s in data:
            if len(s[0]) == 4:#城市
                #print s[0],s[1].decode('unicode_escape')
                citys.append({"id":s[0],"name":s[1].decode('unicode_escape')})
            
        province_id = len(data[0][0])==4 and data[0][0] or data[0][0][0:4]
    
        #只處理列表中的幾個省
        if provinceMap.has_key(int(province_id)):
            province['id'] = province_id
            province['name'] = provinceMap[int(province_id)]
            province['citys'] = citys
            provinceList.append(province)
        
    return provinceList


#獲得某個的市級區域所有縣區的學校
def getCitySchool(content):
    soup = BeautifulSoup(content)
    
    #某個城市的中學列表
    citySchoolData = []
    #縣區的列表
    townlist = soup.findAll('a',href="#highschool_anchor")    

    for town in townlist:
        d = {}
        d['name'] = getUnicodeStr(town.string)
        d['id'] = town['onclick'][24:38]
        townSchools = []
        #獲得每個縣的中學列表
        for school in soup.find('ul',id=d['id']).findChildren('a'):
            townSchools.append(getUnicodeStr(school.string))
        d['schoollist'] = townSchools
        
        citySchoolData.append(d)
    
    return citySchoolData

conn = MongoClient(db_host)
db = conn.openclass
juniorschool = db.juniorschool

if __name__ == "__main__":
    provinceList = getProvinceData();
    print provinceList
    
    for province in provinceList:
        citys = province['citys']
        #print province
        if citys:#有城市,說明不是直轄市
            for city in citys:
                data = {"id":city['id'],"name":city['name'],"data":getCitySchool(getTownHtml(city['id']))}     
                print "insert into mongodb:",city['name']
                juniorschool.insert(data)          
        
        else:#直轄市
            data = {"id":province['id'],"name":province['name'],"data":getCitySchool(getTownHtml(province['id']))}   
            print "insert into mongodb:",province['name']           
            juniorschool.insert(data)
執行玩程式碼,會把相關的資料存到mongodb,如下所示:

相關推薦

人人獲取全國中學資訊市縣

最近有個專案需要用到全國中學的資訊,自己整理肯定事很難可行了,在網上看到這一片文章:用HttpClient抓取人人網高校資料庫(http://www.iteye.com/topic/826988),就想能不能從人人網上把這部分資訊搞下來。下面是實現步驟: 1 首先firef

java 獲取伺服器裝置資訊監控伺服器

package com.system; import java.net.InetAddress; import java.net.UnknownHostException; import org.hyperic.sigar.CpuInfo; import org.hyper

c#獲取中國三級行政區域劃分市縣以及縣級經緯度demo

1 定義三級model [XmlRoot("country")] public class Country { [XmlElement("provinces")] public List<Prov

攜程 Apollo 配置中心 | 學習筆記 如何Apollo配置中心獲取實時更新配置資訊熱釋出

本章將介紹Apollo配置中心的熱釋出。其實在第九章就有提到Apollo配置中心提供的熱釋出,及實時獲取最新配置資訊。通過API的方式獲取API 方式     API方式靈活,功能完備,配置值實時更新(熱釋出),支援所有Java環境。TestController4.java@

55-- 簡單爬取人人個人首頁資訊

# 簡單爬取人人網個人首頁資訊from urllib import request base_url = 'http://www.renren.com/964943656' headers = { "Host" : "www.renren.com", "Co

c# 獲取所有絡卡的資訊IP。MAC

using System.Net; using System; using System.Management; using System.Runtime.InteropServices; public class getIP { [DllImport("Iphl

java提取(獲取)部落格資訊內容

package com.wbg.my.service; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.*; import java.util.regex.Matcher

iOS開發-Object-C獲取手機裝置資訊UIDevice

一、獲取UiDevice裝置資訊 // 獲取裝置名稱 NSString *name = [[UIDevice currentDevice] name]; // 獲取裝置系統名稱 NSString *systemName = [[UIDevice currentDevice] systemName

js 獲取手機平衡儀陀螺儀角度資訊

html5中的deviceorientation事件,此事件是檢測裝置方向變化時的事件。其常用屬性為alpha(x)、beta(y)、gamma(z)。 alpha:左右旋轉 beta:前後旋轉 g

WMS GetFeatureInfo (Layers)——WMS獲取要素資訊圖層

Demonstrates the use of the layers option in the ol.format.WMSGetFeatureInfo format object, which allows features returned by a single WMS GetFeatureIn

如何獲取微信公眾號使用者的個人資訊包括OpenId

最近,對微信公眾號有點興趣,就自己研究了研究裡面的一些內容,發現還挺有意思的,而且通過微信公眾號可以呼叫一些比較有意思的介面,就比如百度開發服務平臺點選進入裡面的很有介面,就比較常見的翻譯,語音識別,地理位置等等,都挺好的。好了,不多說,進入正題好了。我想,做微信公眾號開發的

微信公眾號開發__微信網頁授權並獲取使用者基本資訊是否關注公眾號、頭像、暱稱等

        本人最近要做微信公眾號網頁開發的專案,其中有個需求是判斷使用者是否關注公眾號,由於之前沒有接觸過微信授權的東西,所以提前開始做調研。在度娘上看了好多部落格、百度知道、百度經驗、知乎問答等,還仔細閱讀了微信公眾平臺開發文件,大致瞭解到:        微信網頁授

QStorageInfo獲取磁碟資訊非常詳細

QStorageInfo類提供了系統當前掛載的儲存和驅動器的相關資訊,包括它們的空間,掛載點,標籤名,檔案系統名。 一般,我們可以使用特定的檔案或目錄來建立一個QStorageInfo類的物件,也可以使用其靜態方法mountedVolumes()來得到當前系統中掛載的所有檔案系統的列表;還可以使用root(

【小程式】java 後臺獲取使用者資訊解密encryptedData

首先java 後端依賴兩個jar <dependency> <groupId>org.codehaus.xfire</groupId> <artifactId>xfire-core</artifac

java使用siger 獲取伺服器硬體資訊CPU 記憶體 網路 io等

import java.net.InetAddress;import java.net.UnknownHostException;import java.util.Map;import java.util.Properties;import org.hyperic.sigar.CpuInfo;import o

【OAuth2.0網頁授權】根據access_token和openId獲取使用者基本資訊Senparc.Weixin.MP.dll

寫在回撥的URL頁面裡,access_token和openId根據code獲取 OAuthUserInfo userInfo = OAuthApi.GetUserInfo(a

爬取美團的美食點評資訊含頁面分析過程

寫在前面:        憑藉興趣寫了很多爬蟲的小程式,但是都沒有以博文的形式分享出來。爬取美團網的資料是因為課題研究需要,已經將深圳所有的美團店鋪評論資料爬取完畢(大眾點評和百檽米的相應區域也已爬取完畢,對爬蟲有興趣可以看我的GitHub主頁:https://github

Python之獲取平臺和作業系統資訊platform模組

#獲取作業系統的一些資訊: import platform platform.platform() #獲取作業系統名稱及版本號,'Linux-3.13.0-46-generic-i686-with-Deepin-2014.2-trusty' platform.

利用JNI方法,通過WMI獲取本地硬體資訊主機板型號,硬碟序列號,CPU引數等

因為有幾臺伺服器是windows 2000的,之前採用的WMIC方法不適用(windows 2003開始有),更不用說WMI .NET了(採用.NET Framework 3.5),只能採用JNI的方法,通過C++來呼叫本地WMI介面來查詢資料。幸好,這次WMI從windo

年齡大到小輸出通訊錄資訊OJ上通過,但是DEVC++上一直亂碼和要多輸幾位

結構 第5題 【描述】 建立一個通訊錄結構,包括姓名、生日和電話號碼,輸入n(3≤n≤50)個朋友的資訊,按年齡從大到小的順序依次輸出其資訊。 【輸入】 輸入第一行為正整數n(3≤n≤50),表示朋友數量。 下面n行為朋友資訊,每行包括姓名、生日和電話號碼,以空格間隔。