Python爬蟲案例-獲取最新的中國行政區域划分


源網頁:中國統計局標准 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)

 


免責聲明!

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



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