初学者——Selenium爬取统计局年度人口分布公开数据代码

初学者——Selenium爬取统计局年度人口分布公开数据代码

(仅爬虫练习,侵删)

数据来源:统计局官网
数据去向:EXCEL表格
数据处理工具:SELENIUM ,GOOGLE浏览器
注意事项:

1.代码中的浏览器驱动地址以及存储CSV地址需要更换本地地址;
2.存储数据:一张表 = 一个工作薄,目录层级关系在工作薄名字上进行展示;

话不多说,直接上代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
from lxml import etree
from lxml import html
from bs4 import BeautifulSoup
import selenium.webdriver.support.ui as ui
import requests
import pandas as   pd
import time
import json
import openpyxl as op
import urllib.request
import re
import hashlib
import datetime
#写入指定的EXCEL文件
def  write_to_excel(fileName,sheetname,title,data):
    try:
        workbook = op.load_workbook(fileName)
        worksheet1 = workbook.create_sheet(sheetname)
        worksheet1.append( title)
        for j in range(len(data)):
            insertData = data[j]
            worksheet1.append(insertData)
        workbook.save(fileName)  # 关闭表
    except Exception as e:
        print('list index out of range')
        print(e)
        
# 获取指定路径下的级数个数
def getElementCnt(resp,path,element):
    param1 = resp.xpath(path)
    try:
        param_code = html.tostring(param1[0])
        param_cnt = str(param_code).count(element)
        return param_cnt
    except Exception as e:
#         print("Calculating Element Count Wrong!")
        if e is 'list index out of range':
            return 0
        else:
#             print(e)
            return 0
        
    
#判断下一级个数是否存在
def judgeHasNextFloor(resp,path,element):
    a = getElementCnt(resp,path,element)
    if a is not 0:
        return true
    else:
        return false
#清除数据自身带来的符号
def cleanString(str1):
    return str1.replace('[','').replace(']','').replace('\'''','')
# #获取数据列级信息
def getHeadData(resp):
    headlists = []
    column_cnt = getElementCnt(resp,'/html/body/div[5]/div[2]/div/div[2]/div[2]/div[2]/div/div[1]/table/thead/tr','<th')
    tbhead_list = resp.xpath('/html/body/div[5]/div[2]/div/div[2]/div[2]/div[2]/div/div[1]/table/thead/tr')
    for tbhead in tbhead_list: 
        for i in range(column_cnt):
            i +=1
            head_pri = tbhead.xpath('./th['+str(i)+']/strong/text()')
            head=str(head_pri).replace('[','').replace(']','').replace('\'''','')
            headlists.append(head)
    print("Columns:"+str(headlists))
    return headlists

#获取数据行级信息 
def getRowsData(resp):
    bodylists = []
    tbbody_list = resp.xpath('/html/body/div[5]/div[2]/div/div[2]/div[2]/div[2]/div/div[3]/table/tbody')
    row_cnt = getElementCnt(resp,'/html/body/div[5]/div[2]/div/div[2]/div[2]/div[2]/div/div[3]/table/tbody','<tr')
    column_cnt = getElementCnt(resp,'/html/body/div[5]/div[2]/div/div[2]/div[2]/div[2]/div/div[1]/table/thead/tr','<th')
    for tbbody in  tbbody_list:
        for j in range(row_cnt):#rows
            bodylist = []
            j += 1
            for k in range(column_cnt):#columns
                k += 1
                body_pri = tbbody.xpath('./tr['+str(j)+']/td['+str(k)+']/text()')
                body=str(body_pri).replace('[','').replace(']','').replace('\'''','')
                bodylist.append(body)
            bodylists.append(bodylist)
            print("Rows:"+str(bodylist))
    return bodylists

def printHeadAndData(resp,fileName,sheetname):
    headlists = getHeadData(resp)
    bodylists = getRowsData(resp)
    write_to_excel(fileName,sheetname,headlists,bodylists)
# 获取网页驱动
driver = webdriver.Chrome(executable_path='D:/test/chromedriver.exe')
wait = ui.WebDriverWait(driver,10)


# 获取网页信息
driver.get('https://data.stats.gov.cn/easyquery.htm?cn=C01')
# 针对Google私密设置
click_goon = driver.find_element_by_xpath("/html/body/div/div[3]/p[2]/a[text()='继续前往data.stats.gov.cn(不安全)']")
driver.execute_script("arguments[0].click();", click_goon)
driver.get('https://data.stats.gov.cn/easyquery.htm?cn=C01')
driver.switch_to.default_content()
time.sleep(2)


# 设置页面功能维度转换
converse=driver.find_element_by_xpath("/html/body/div[11]/ul/li[2]/a[text()='转置']")
driver.execute_script("arguments[0].click();", converse)
time.sleep(2)
#设置展示最近20年数据,暂未成功
# ele = driver.find_element(By.XPATH,'(//*[@title="最近20年"])[1]') 
# ActionChains(driver).move_to_element(ele).perform() # 鼠标悬停


# 定位鼠标悬停元素 触发下拉框菜单
# # 选择第一层单位
# driver.find_element(By.XPATH,'//*[@id="treeZhiBiao_2_span"]').click() 
# # 选择第二层单位
# driver.find_element(By.XPATH,'//*[@id="treeZhiBiao_30_span"]').click() 
# time.sleep(2)

# 获取网页源代码
resp = driver.page_source
resp = etree.HTML(resp)

# 获取一级菜单栏地址和个数
floor1_cnt = getElementCnt(resp,'/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul','<li')
print("The number of data`s floors is "+str(floor1_cnt))

basepath = '/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul'
fileName = 'E:/User/datamining/c_data.xlsx'  

floor1_id_list = []
floor1_name_list = []
floor2_id_list = []
floor2_name_list = []
floor3_name_list = []
floor3_id_list = []
floor4_name_list = []
floor4_id_list = []
#判断菜单层级是否为0 ,为0时记录当前层级ID值;不为0时继续遍历下一级;下面展示的就是不为0时获取菜单的ID和名称
def converseMenu(cnt,basepath):
    floor_list = []
    floor_name_list = []
    floor_id_list = []
    if cnt is not 0:
        for c in range(cnt):
            c += 1
            floor = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul/li['+str(c)+']/a/span[2]')
            driver.execute_script("arguments[0].click();", floor)
            time.sleep(2)
            resp2 = driver.page_source
            resp2 = etree.HTML(resp2)
        
            cnt2 = getElementCnt(resp2,'/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul/li['+str(c)+']/ul','<li')
            time.sleep(1)
            print(floor.text +'的下一层菜单个数为 = '+str(cnt2))
            if cnt2 is not 0 :
                for c2 in range(cnt2):
                    c2 += 1
                    floor2 = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul/li['+str(c)+']/ul/li['+str(c2)+']/a/span[2]')
                    driver.execute_script("arguments[0].click();", floor2)
                    time.sleep(1)
                    resp3 = driver.page_source
                    resp3 = etree.HTML(resp3)
                    cnt3 = getElementCnt(resp3,'/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul/li['+str(c)+']/ul/li['+str(c2)+']/ul','<li')
                    print(floor.text+'_'+floor2.text +' 下一层菜单个数为 '+str(cnt3))
                    if cnt3 is not 0 :
                        for c3 in range(cnt3):
                            c3 += 1
                            floor3 = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul/li['+str(c)+']/ul/li['+str(c2)+']/ul/li['+str(c3)+']/a/span[2]')
                            driver.execute_script("arguments[0].click();", floor3)
                            time.sleep(1)
                            resp4 = driver.page_source
                            resp4 = etree.HTML(resp4)
                            cnt4 = getElementCnt(resp4,'/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul/li['+str(c)+']/ul/li['+str(c2)+']/ul/li['+str(c3)+']/ul','<li')
                            print(floor.text+'_'+floor2.text+'_'+floor3.text +' 下一层菜单个数为 '+str(cnt4))
                            if cnt4 is not 0 :
                                for c4 in range(cnt4):
                                    c4+=1
                                    floor4 = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/div[1]/div/ul/li/ul/li['+str(c)+']/ul/li['+str(c2)+']/ul/li['+str(c3)+']/ul/li['+str(c4)+']/a/span[2]')
                                    driver.execute_script("arguments[0].click();", floor4)
                                    time.sleep(1)
                                    resp4_5 = driver.page_source
                                    resp4_5 = etree.HTML(resp4_5)
                                    printHeadAndData(resp4_5,fileName,floor.text+'_'+floor2.text+'_'+floor3.text+'_'+floor4.text)
                                    floor4_name = floor4.text
                                    floor4_id = floor4.get_attribute('id')
                                    floor_name_list.append(floor4_name)
                                    floor_id_list.append(floor4_id)
                                    floor4_name_list.append(floor4_name)
                                    floor4_id_list.append(floor4_id)
                            else:
                                resp3_4 = driver.page_source
                                resp3_4 = etree.HTML(resp3_4)
                                printHeadAndData(resp3_4,fileName,floor.text+'_'+floor2.text+'_'+floor3.text)
                                floor3_name = floor3.text
                                floor3_id = floor3.get_attribute('id')
                                floor_name_list.append(floor3_name)
                                floor_id_list.append(floor3_id)
                                floor3_name_list.append(floor3_name)
                                floor3_id_list.append(floor3_id)
                    else:
                        resp2_3 = driver.page_source
                        resp2_3 = etree.HTML(resp2_3)
                        printHeadAndData(resp2_3,fileName,floor.text+'_'+floor2.text)
                        floor2_name = floor2.text
                        floor2_id = floor2.get_attribute('id')
                        floor_name_list.append(floor2_name)
                        floor_id_list.append(floor2_id)
                        floor2_name_list.append(floor2_name)
                        floor2_id_list.append(floor2_id)
            else:
                resp1_2 = driver.page_source
                resp1_2 = etree.HTML(resp1_2)
                printHeadAndData(resp1_2,fileName,floor.text)
                floor_name = floor.text
                floor_id = floor.get_attribute('id')
                floor_name_list.append(floor_name)
                floor_id_list.append(floor_id)
                floor1_name_list.append(floor_name)
                floor1_id_list.append(floor_id)
        floor_list.append(floor_name_list)
        floor_list.append(floor_id_list)   
        return floor_list
    else:
        return false
    

# 第一层
floor1_list = converseMenu(floor1_cnt,basepath)
# print("The click floors are as list: "+str(floor_list))        
# print("The first floors are as list: "+str(floor1_name_list))        
# print("The second floors are as list: "+str(floor2_name_list))   


   
driver.close()
driver.quit()

爬虫页面显示:
在这里插入图片描述
EXCEL表格展示数据,目录间的上下级关系通过下划线“_”连接的,表格数量非常多:
在这里插入图片描述

欢迎小伙伴留言讨论哦~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当涉及到爬取网页数据时,有几种常见的方法和工具可以使用。以下是一个简单的教程,介绍了一种常见的爬取网页数据的方法: 1. 选择合适的编程语言:爬取网页数据通常需要使用编程语言来编写代码。常见的选择包括Python、Java和JavaScript等。其中,Python是最受欢迎的语言之一,因为它有许多强大的库和框架可以用于爬虫开发。 2. 安装必要的库和工具:对于Python来说,你可以使用一些流行的库来进行网页数据爬取,例如Requests、BeautifulSoup和Scrapy等。你可以使用pip命令来安装这些库。 3. 发送HTTP请求:使用HTTP请求库(如Requests)发送HTTP请求到目标网页。你可以发送GET请求获取网页内容,或者发送POST请求提交表单数据。 4. 解析网页内容:使用HTML解析库(如BeautifulSoup)解析网页内容。这样你就可以提取出你感兴趣的数据,例如标题、链接、文本等。 5. 存储数据:将提取到的数据存储到合适的地方,例如数据库、CSV文件或者Excel表格中。 6. 处理反爬机制:有些网站可能会采取反爬机制,例如限制访问频率、验证码等。你可能需要使用代理IP、用户代理、验证码识别等技术来绕过这些限制。 7. 遵守法律和道德规范:在进行网页数据爬取时,务必遵守相关的法律和道德规范。尊重网站的隐私政策和使用条款,并确保你的爬虫行为不会对网站造成过大的负担。 希望以上教程对你有所帮助!如果你有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值