前言
在做用户收货地址管理的时候 需要用到省 市 县 城镇 数据
但是网上普遍都只有 省 市 县 而没有城镇(街道)的数据
于是就自己动手 丰衣足食了~
顺便记录一下 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;
}
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于