最近有一个任务,需要采集一批知名学者的性别信息。该任务的难点在于提供学者信息的网站并不会主动标注学者的性别性别,因此只能靠别的方法了。

对一个普通人来说,在网上判断一个人的性别的最快的方式就是看他的照片了,例如:

因此,我想可以利用爬虫抓取人物的头像照片,再利用现在已经很成熟的人脸检测技术,识别人物的性别。

一个简单的方案是:
  1. 利用 Google 搜索人物姓名,Google 通常会在展示知名人物搜索结果的同时,在右侧以一个小卡片的形式展示人物的维基百科简介以及照片等内容,这里的照片可以抓取下来;
  2. 利用百度 AI 提供的人脸检测 API,将人物的照片通过 API 识别人物的性别,百度的人脸检测 API 每天免费提供了1000次的使用次数,可以完成较小规模数据的人脸检测人物。

一、Google搜索结果抓取

为了方便,我直接用 Selenium 来抓取Google搜索结果。

Selenium 主要是用于自动化Web应用程序测试,也经常被用来作为动态网页抓取的工具。Selenium的官方文档在此,提供了Java、Python、C#等主流语言的API和文档,很好上手。网上也有相当多对Selenium介绍的博客, 大家可以参考其他作者的介绍。用 Selenium 的好处是不用自己去处理Cookie的问题,也不用担心网站动态渲染的问题;也存在最大的缺点就是速度慢(因为它会打开浏览器来加载网页)。当然,Google搜索的结果也是可以直接用传统方式抓取静态页面、找到人物照片的,相信聪明的你能做到的。

我是用Java写的,这一部分的主要代码如下:

/**
* 由人名从Google搜索结果中查找人物照片
*
* @param name 人物姓名
* @return 是否找到人物照片
*/
public boolean fetchOneByGoogle(String name) throws IOException {
WebDriver webDriver = new ChromeDriver(); String url = "https://www.google.com/search?source=hp&q=" + URLEncoder.encode(name, "utf-8");
String imgName = name + ".jpg";
webDriver.get(url); String imgDivCss = "#media_result_group > div > div._Sle._rcb.kno-ibrg > div > div > div > div > div > div > div > div";
List<WebElement> picDivs = webDriver.findElements(By.cssSelector(imgDivCss));
for (WebElement picDiv : picDivs) {
WebElement imgElement = picDiv.findElement(By.cssSelector("img"));
String imgSrc = imgElement.getAttribute("src");
if (saveImgSrcToFile(imgSrc, imgName)) {
return true;
}
}
return false;
} /**
* 将 img 标签中 src 内容存储为图片文件
*
* @param imgSrc img 标签中的 src 内容
* @param imgName 要存储的文件名称
* @return 是否成功获取并保存了图片
*/
private boolean saveImgSrcToFile(String imgSrc, String imgName) throws IOException {
logger.info("Img-src: {}", imgSrc);
if (imgSrc.contains(",")) {
String imgBase64 = imgSrc.split(",")[1];
byte[] decode = Base64.getDecoder().decode(imgBase64);
FileOutputStream outputStream = new FileOutputStream("E:\\face\\" + imgName);
outputStream.write(decode);
outputStream.close();
return true;
}
return false;
}

以上fetchOneByGoogle方法是由人名从Google搜索结果中查找人物照片,并用saveImgSrcToFile将图片保存到文件。

Donald Trump为例,Google搜索截图如下所示:

人物卡片中的第一张照片就是我们想要获取的人物照片。通过浏览器的审查元素查看图片所在div的css路径为#media_result_group > div > div._Sle._rcb.kno-ibrg > div > div > div > div > div > div > div > div > img (我这里分析的比较粗糙,大致可以工作)。

img标签中的scr内容为src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgH...,是图片经过Base64编码后的结果,将data:image/jpeg;base64,后的内容用Base64解码为byte数组直接保存到文件就行。

抓取结果如下:

二、百度人脸检测

百度 AI 对人脸检测的介绍在这里,注册后就可以使用。同时还提供了Java、Python等主流语言的SDK下载,调用API也很方便。

我这里的简单代码示例如下:

public static String getGender(String fileName) {
// 初始化一个FaceClient
AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY); // 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000); // 调用API
HashMap<String, String> options = new HashMap<>();
options.put("face_fields", "gender");
JSONObject res = client.detect(BASE_FILE_PATH + fileName, options);
if (!res.has("result")) {
return null;
}
JSONArray results = res.getJSONArray("result");
if (results.length() < 1) {
return null;
}
JSONObject result = results.getJSONObject(0);
if (!result.has("gender")) {
return null;
}
return result.getString("gender");
}

因为我想要的识别性别,所有就在这一行代码options.put("face_fields", "gender");增加结果字段gender

API返回的结果是JSON格式的,简单解析一下就能得到gender数据。

针对上面Donald Trump的照片,人脸检测的结果是:

Donald Trump: male

再次测试搜索Hillary Clinton,得到的结果是:

Hillary Clinton: female,没毛病。

三、小结

通过以上两个步骤,此次任务中大部分的学者性别信息都采集到了。当然,还存在一下不完美的情况:搜索结果的第一张图片不是人物的头像,或者Google并没有该学者的人物信息卡片。其次,在现在我数据量少的情况下调用百度 AI 的接口是可行,但是当以后有数据量大的任务时,继续采用这个方案就需要付费了。

下一步的展望

这个方案还有可以改进的地方:

  1. 可以考虑从 Google 搜索结果中找到学者主页,从学者主页中抓取照片;
  2. 可以考虑自己训练一个用人脸照片检测性别的分类器,支持大数据量的情况。

我在这里仅是抛砖引玉,欢迎各位大神提出指正,或者分享更好的方案。

Google+百度,自动识别知名人物的性别的更多相关文章

  1. C++ 写的地图控件,支持google 百度 在线离线地图

    C++处理google  百度地图在网上查阅了很多都是通过浏览器方式显示地图信息, 跟我目前项目很不符合, 所以仔细研究了一下C++方式显示地图.通过地图投影以及墨卡托投影,在通过平面地图计算经纬度. ...

  2. OpenStreetMap/Google/百度/Bing瓦片地图服务(TMS)

    开源与成熟商业的瓦片地图服务(TMS  2  WMTS),都有如下共同的特性,基本成为了标准: (1) 坐标系:WGS84 (2) 投影:墨卡托投影(Marcator,正轴等角圆柱投影) ------ ...

  3. [转]OpenStreetMap/Google/百度/Bing瓦片地图服务(TMS)

    转自:https://blog.csdn.net/youngkingyj/article/details/23365849 开源与成熟商业的瓦片地图服务(TMS  2  WMTS),都有如下共同的特性 ...

  4. google,百度地图POI下载

    百度,google POI下载工具是可以对任意矩形范围,以及任意省市级区域的兴趣点数据进行下载,可以支持多线程下载,按分类下载,以及按关键字下载. 线程数可以自由设置16线程之内.下载格式为excel ...

  5. 2分钟就能学会的【Google/百度搜索大法】了解一下?

    之前我在知乎回答了「日常生活中有哪些十分钟就能学会并可以终生受用的技能」,现在也整理分享给公众号的朋友们. 作为一个入坑8年国际贸易的老阿姨,真心推荐[google搜索大法](同样适用于百度). 2分 ...

  6. <爬虫>利用BeautifulSoup爬取百度百科虚拟人物资料存入Mysql数据库

    网页情况: 代码: import requests from requests.exceptions import RequestException from bs4 import Beautiful ...

  7. python3 - 通过BeautifulSoup 4抓取百度百科人物相关链接

    导入需要的模块 需要安装BeautifulSoup from urllib.request import urlopen, HTTPError, URLError from bs4 import Be ...

  8. 百度首席科学家 Andrew Ng谈深度学习的挑战和未来(转载)

    转载:http://www.csdn.net/article/2014-07-10/2820600 人工智能被认为是下一个互联网大事件,当下,谷歌.微软.百度等知名的高科技公司争相投入资源,占领深度学 ...

  9. Google地图,Baidu地图数据供应商

    http://janwen.iteye.com/blog/488659 Google百度  我老以为百度,Google的地图产品是自己开发的,原来是别人提供的数据, 百度的数据提供商有 北京世纪高通科 ...

随机推荐

  1. JavaScript Event 事件 事件流 事件对象 事件处理程序 回调函数 error和try...catch和throw

    参考资料: 慕课网 DOM事件探秘    js事件对象 处理 事件驱动: JS是采用事件驱动的机制来响应用户操作的,也就是说当用户对某个html元素进行操作的时候,会产生一个事件,该事件会驱动某些函数 ...

  2. Tomcat启动报错java.net.AbstractPlainSocketImpl(java/net/AbstractPlainSocketImpl.java:178:-1)Struts在网络复杂情况下启动报错解决办法

    SSH项目 在网络复杂的情况(具体规律未知)下,Tomcat启动时,报如下错误: [ERROR] 2014-08-12 14:52:58,484 [org.apache.struts2.dispatc ...

  3. qt 拷贝文件设置进度条

    /** * @brief FuncModuleWin::copyFile * @param fromFIleName 优盘里面的文件 * @param toFileName 拷贝到/bin里面的启动文 ...

  4. 使用spring aop遇到的坑

    1.aop 切点配置无误但只对控制器无效. 检测你的aop开启配置是否放在了spring配置文件中,如果是请把它移到mvc配置文件中. 我们知道当spring项目使用了spring mvc时,项目是存 ...

  5. java实现哈弗曼树和哈夫曼树压缩

    本篇博文将介绍什么是哈夫曼树,并且如何在java语言中构建一棵哈夫曼树,怎么利用哈夫曼树实现对文件的压缩和解压.首先,先来了解下什么哈夫曼树. 一.哈夫曼树 哈夫曼树属于二叉树,即树的结点最多拥有2个 ...

  6. Math类中常用方法

    public static int abs(int a) , public static long abs(long a), public static float abs(float a),  pu ...

  7. 并发包交换数据Exchanger

    /** * * @描述: 用于实现两个人之间的数据交换,每个人完成一定的事务后想与对方交换数据,第一个先拿出数据的人一直等待 * 直到第二个人拿到数据 到来时,才能彼此交换数据. * @作者: Wnj ...

  8. 使用UIScreenEdgePanGestureRecognizer写iOS7侧边栏

    使用UIScreenEdgePanGestureRecognizer写iOS7侧边栏 A UIScreenEdgePanGestureRecognizer looks for panning (dra ...

  9. Oracle数据库设计实例-实时生产效率系统数据库设计

    Oracle数据库设计实例-实时生产效率系统数据库设计 引言 1.1 设计前提 某部门经理要求IT部门设计一个流水线实时生产效率系统,用来统计实时的生产量和效率.流水线有数百条,实时间隔为1min. ...

  10. oracle获得ddl语句

    dbms_metadata.get_ddl()用于获取对象的DDL,其具体用法如下.注意:在sqlplus里,为了更好的展示DDL,需要设置如下参数:set line 200set pagesize ...