源網頁:中國統計局標准 http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/
打開網頁后可以分析出行政區域划分共分為5層

根據傳入參數,生成網頁地址時需要1-3層的只傳本身以及 4層及以后的增加當前省份的前綴。
#生成實際需要解析的頁面地址 def geturl(level,url,code): if level<4: url=url else: url=code[0:2]+'/'+url url='http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/'+url return url
標簽1-5分別不同
#獲取需要解析的標簽 def getlevelclass(level): LevelDict={1:"provincetr",2:"citytr",3:"countytr",4:"towntr",5:"villagetr"} return LevelDict[level]
根據網頁上的標簽以及實際地址去獲取所需要的網頁內容
#設置頭信息 def getheaders(): headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'} return headers #獲取網頁內容 def Get_WebContent(url,level): headers=getheaders() res=urllib.request.Request(url,None, headers=headers) i=1 while i<4: try: response=urllib.request.urlopen(res) i=100 except error.URLError as e: print('執行第'+str(i)+'次錯誤,'+e.reason) i=i+1 time.sleep(10) html_content=response.read() #將html從gb2312編碼轉換到utf-8的編碼 html_content = html_content.decode('gb2312', 'ignore').encode('utf-8') soup = BeautifulSoup(html_content, 'html.parser', from_encoding='utf-8') #獲得內容 levelclass='.'+getlevelclass(level) souplist=soup.select(levelclass) return souplist
根據輸出值需要創建解析第一層與其他層的兩種函數。
#conding=utf-8 from bs4 import BeautifulSoup #用於解析第二層,內容(Code,Pronvince,urls) def Get_Child(souplist,parentid,level): SQLLIST=[] for provincesoup in souplist: url_tds=provincesoup.find_all('a',href=True) a=1 for td in url_tds: if a%2==1: code=td.get_text() urls=td['href'] else: provience=td.get_text() row=(code,provience,parentid,level,urls) SQLLIST.append(row) a=a+1 return SQLLIST #用於解析第一層,內容(Pronvince,urls),Code=urls中的數字部分 def Get_Main(souplist,parentid,level): SQLLIST=[] for provincesoup in souplist: url_tds=provincesoup.find_all('a',href=True) for td in url_tds: provience=td.get_text() urls=td['href'] code=td['href'].replace('.html', '') row=(code,provience,parentid,level,urls) SQLLIST.append(row) return SQLLIST #實際調用的獲取值函數函數 def GetDetail(souplist,level,parentid): if level==1: SQLLIST=Get_Main(souplist,parentid,level) else: SQLLIST=Get_Child(souplist,parentid,level) return SQLLIST
SQLSERVER表
CREATE TABLE [dbo].[China_Position]( [ID] [int] IDENTITY(0,1) NOT NULL, [Code] [nvarchar](20) NULL, [Name] [nvarchar](40) NULL, [Name_Short] [nvarchar](20) NULL, [ParentID] [int] NULL, [Level] [int] NULL, [Urls] [nvarchar](200) NULL, [IsFinish] [smallint] NOT NULL )
def DataInsert(ValueList): SQLStr="INSERT INTO [dbo].[China_Position]([Code] ,[Name] ,[ParentID],[Level] ,[Urls]) VALUES(%s ,%s ,%d,%d,%s) " SqlInsert(SQLStr,ValueList) #獲取待運行的任務 def GetTaskList(level): SQLStr="""SELECT v1.[ID] ,v1.[Level]+1 as [Level] ,v1.[Urls] ,v1.Code FROM [dbo].[China_Position] v1 with(nolock) where [IsFinish]=0 And Level=""" + str(level-1) cur=SqlSelect(SQLStr) TaskList=[] for row in cur: rows=(row[0],row[1],row[2],row[3]) TaskList.append(rows) return TaskList
#記錄執行成功日志 def RecordLog(ID): SQLStr="update [dbo].[China_Position] set IsFinish=1 where ID="+str(ID) SqlDelete(SQLStr)
執行最終的代碼,獲取level1-3層的數據。
for i in range(1,4): #獲取第幾層的待執行任務 TaskList=GetTaskList(i) for CTask in TaskList: parentid=CTask[0] level=CTask[1] url=CTask[2] Code=CTask[3] #獲取真實的網頁 url=geturl(level,url,Code) #獲取網頁內容 souplist=Get_WebContent(url,level) #待插入數據路的列表 ValueList=GetDetail(souplist,level,parentid) #插入數據庫 DataInsert(ValueList) #記錄成功日志,下次執行時不執行已執行的任務 RecordLog(parentid)
