前言
在做用户收货地址管理的时候 需要用到省 市 县 城镇 数据 但是网上普遍都只有 省 市 县 而没有城镇(街道)的数据 于是就自己动手 丰衣足食了~ 顺便记录一下 selenium 爬虫的使用
国家统计局官方地址
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/index.html
安装 Selenium
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.14.0</version> </dependency>
安装 Chrom Driver 驱动 (使用 Chrom 浏览器爬取)
导入 Chrom Driver 支持的 Maven
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-chrome-driver</artifactId> <version>3.9.1</version> </dependency>
除了导入 Maven 还需要导入驱动
驱动下载地址 https://www.seleniumhq.org/download/
可以看到 支持的浏览器比较多 我这里选择的是谷歌的 Google Chrome Driver (需要本机安装 Chrome 浏览器)
选择运行环境下载 有 Linux Mac Window 的驱动
接下来就是代码初始化了
//配置ChromeDriver驱动路径 System.setProperty("webdriver.chrome.driver", "/driver/chromedriver_win32/chromedriver.exe"); //构建 WebDriver WebDriver webDriver = new ChromeDriver();
安装 Phantomjs 无头浏览器驱动 (使用 Phantomjs 爬取)
调用 Chrome 驱动的话 会自动打开 Chrome 浏览器进行调试
而大部分情况下 应该是不需要去打开 Chrome 浏览器的 这时候就可以用 Phantomjs 驱动了
下载地址是:http://phantomjs.org/download.html
选择对应的环境下载 有 Windows Linux Mac
下载了驱动后 还需要导入一个 Maven 然后就是初始化了
<dependency> <groupId>com.github.detro</groupId> <artifactId>ghostdriver</artifactId> <exclusions> <exclusion> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> </exclusion> </exclusions> <version>2.1.0</version> </dependency>
代码初始化
//配置phantomjs 驱动路径 System.setProperty("phantomjs.binary.path", "/driver/windows/phantomjs.exe"); WebDriver webDriver = new PhantomJSDriver();
解析数据
我们打开 要爬取的网站:http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/index.html 然后打开开发者模式
可以看到 每一行的省份 都在每一个 class 为 provincetr 的 tr 标签里 而每一个省份 又在 provincetr 里面的 td 标签 中的 a 标签里面
先爬取省份 代码如下:
File file = new File(""); //配置驱动路径 System.setProperty("webdriver.chrome.driver", file.getAbsolutePath() + "/driver/chromedriver_win32/chromedriver.exe"); WebDriver webDriver = new ChromeDriver(); webDriver.get("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/index.html"); //查询classname为provincetr的标签 List<WebElement> provincetr = webDriver.findElements(By.className("provincetr")); for (WebElement webElement : provincetr) { //按标签名查找 查找a标签 List<WebElement> a = webElement.findElements(By.tagName("a")); for (WebElement element : a) { System.out.println("省份:"+element.getText()); } }
最后输出结果如下 (我就不全部贴出来了)
省份:北京市 省份:天津市 省份:河北省 .....
然后我们接着分析城市数据 从省份 随便点一个进入
这时候可以看到 每一行是 代码 和 城市名称 而每一行都在 class 为 citytr 的 tr 标签中
tr 标签里又有两个 a 标签 第一个是 区划代码的 a 标签 第二个 是 城市的 a 标签 我们把第二个 a 标签取出
代码如下
public static void main(String args[]) { File file = new File(""); System.setProperty("webdriver.chrome.driver", file.getAbsolutePath() + "/driver/chromedriver_win32/chromedriver.exe"); System.setProperty("phantomjs.binary.path", file.getAbsolutePath() + "/driver/windows/phantomjs.exe"); WebDriver webDriver = new ChromeDriver(); webDriver.get("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/index.html"); //查询classname为provincetr的标签 List<WebElement> provincetr = webDriver.findElements(By.className("provincetr")); for (WebElement webElement : provincetr) { //按标签名查找 查找a标签 List<WebElement> a = webElement.findElements(By.tagName("a")); for (WebElement element : a) { System.out.println("省份:" + element.getText()); //获取a标签的跳转链接 String src = element.getAttribute("href"); //读取市的数据 scannerCity(src); } } } public static void scannerCity(String src) { WebDriver webDriver = new PhantomJSDriver(); webDriver.get(src); List<WebElement> citytr = webDriver.findElements(By.className("citytr")); for (WebElement webElement : citytr) { List<WebElement> aTag = webElement.findElements(By.tagName("a")); WebElement city = aTag.get(1); System.out.println("城市:" + city.getText()); } //释放 webDriver.close(); }
输出结果如下:
省份:北京市 城市:市辖区 省份:天津市 城市:市辖区 省份:河北省 城市:石家庄市 城市:唐山市 ....
完整的解析省市区 城镇代码
这里是整体 解析数据的代码
public class GetRegion { static { File file = new File(""); System.setProperty("webdriver.chrome.driver", file.getAbsolutePath() + "/driver/chromedriver_win32/chromedriver.exe"); System.setProperty("phantomjs.binary.path", file.getAbsolutePath() + "/driver/windows/phantomjs.exe"); } /** * 构建四个爬虫进程 */ private static WebDriver provinceDriver = new ChromeDriver(); private static WebDriver cityDriver = new ChromeDriver(); private static WebDriver countyDriver = new ChromeDriver(); private static WebDriver towntrDriver = new ChromeDriver(); public static void main(String args[]) throws IOException, InterruptedException { LinkedList<RegionEntry> linkedList = new LinkedList<>(); provinceDriver.get("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/index.html"); //查询classname为provincetr的标签 List<WebElement> provincetr = provinceDriver.findElements(By.className("provincetr")); for (WebElement webElement : provincetr) { //按标签名查找 查找a标签 List<WebElement> a = webElement.findElements(By.tagName("a")); for (WebElement element : a) { System.out.println("省份:"+element.getText()); RegionEntry provinceRegionEntity = new RegionEntry(); provinceRegionEntity.setType(1); provinceRegionEntity.setName(element.getText()); //构建一个ID provinceRegionEntity.setId(IdGeneratorCore.generatorId()); linkedList.add(provinceRegionEntity); //获取a标签的跳转链接 String src = element.getAttribute("href"); //读取市的数据 LinkedList<RegionEntry> citys = scannerCity(provinceRegionEntity.getId(), src); linkedList.addAll(citys); } } Gson gson = new Gson(); String toJson = gson.toJson(linkedList); Files.write(toJson.getBytes(), new File("D://region.json")); System.out.println("处理完毕"); // close 方法:关闭当前窗口,如果浏览器是当前打开的最后一个窗口,则退出浏览器 provinceDriver.close(); cityDriver.close(); countyDriver.close(); towntrDriver.close(); //quit 退出此驱动程序,关闭每个关联窗口。 provinceDriver.quit(); cityDriver.quit(); countyDriver.quit(); towntrDriver.quit(); } /** * 扫描 城市 * * @param supperId * @param src * @return */ public static LinkedList<RegionEntry> scannerCity(Long supperId, String src) throws InterruptedException { LinkedList<RegionEntry> linkedList = new LinkedList<>(); cityDriver.get(src); List<WebElement> citytr = cityDriver.findElements(By.className("citytr")); for (WebElement webElement : citytr) { List<WebElement> aTag = webElement.findElements(By.tagName("a")); WebElement city = aTag.get(1); if (aTag == null || aTag.size() <= 1) { continue; } System.out.println(" 城市:"+webElement.getText()); RegionEntry cityRegionEntity = new RegionEntry(); cityRegionEntity.setType(2); cityRegionEntity.setName(city.getText()); cityRegionEntity.setId(IdGeneratorCore.generatorId()); cityRegionEntity.setSupperId(supperId); linkedList.add(cityRegionEntity); //扫描县城 LinkedList<RegionEntry> countys = scannerCounty(cityRegionEntity.getId(), city.getAttribute("href")); linkedList.addAll(countys); } return linkedList; } /** * 扫描区县 * * @param supperId * @param src * @return */ public static LinkedList<RegionEntry> scannerCounty(Long supperId, String src) throws InterruptedException { LinkedList<RegionEntry> linkedList = new LinkedList<>(); countyDriver.get(src); List<WebElement> countytr = countyDriver.findElements(By.className("countytr")); for (WebElement webElement : countytr) { List<WebElement> aTag = webElement.findElements(By.tagName("a")); if (aTag == null || aTag.size() <= 1) { continue; } System.out.println(" 区县:"+webElement.getText()); WebElement county = aTag.get(1); RegionEntry countytrRegions = new RegionEntry(); countytrRegions.setType(3); countytrRegions.setName(county.getText()); countytrRegions.setId(IdGeneratorCore.generatorId()); countytrRegions.setSupperId(supperId); linkedList.add(countytrRegions); LinkedList<RegionEntry> countys = scannerTowntr(countytrRegions.getId(), county.getAttribute("href")); linkedList.addAll(countys); } return linkedList; } /** * 扫描城镇(街道) * * @param supperId * @param src * @return */ public static LinkedList<RegionEntry> scannerTowntr(Long supperId, String src) throws InterruptedException { Thread.sleep(100); LinkedList<RegionEntry> linkedList = new LinkedList<>(); towntrDriver.get(src); List<WebElement> towntr = towntrDriver.findElements(By.className("towntr")); for (WebElement webElement : towntr) { List<WebElement> aTag = webElement.findElements(By.tagName("a")); WebElement towntrWebElement = aTag.get(1); if (aTag == null || aTag.size() <= 1) { continue; } System.out.println(" 街道:"+towntrWebElement.getText()); RegionEntry towntrRegionEntity = new RegionEntry(); towntrRegionEntity.setType(4); towntrRegionEntity.setName(towntrWebElement.getText()); towntrRegionEntity.setId(IdGeneratorCore.generatorId()); towntrRegionEntity.setSupperId(supperId); linkedList.add(towntrRegionEntity); } //释放 return linkedList; } }
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于