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

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

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

一个简单的方案是:
  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. Ganglia安装

    一.rrdtool安装 1.1 安装依赖包 由于rrdtool依赖的包比较多,而且包之间也存在依赖,故使用yum安装由于服务器无法联网,故使用iso文件创建本地yum源,方法见下: (1)创建iso存 ...

  2. Linux 服务器性能问题排查思路

    一个基于 Linux 操作系统的服务器运行的同时,也会表征出各种各样参数信息.通常来说运维人员.系统管理员会对这些数据会极为敏感,但是这些参数对于开发者来说也十分重要,尤其当你的程序非正常工作的时候, ...

  3. 用phpstudy搭建的lnmp环境下mysql授权远程连接

    1.使用phpstudy安装的mysql没有放置到可以直接调用的目录里,所以只能使用绝对路径来访问: /phpstudy/mysql/bin/mysql -uroot -proot 2.执行use m ...

  4. July 14th 2017 Week 28th Friday

    A life without a dress rehearsal, every day is broadcast live. 人生没有彩排,每天都是现场直播. Every day when I pre ...

  5. jclass和jobject的迷惑

    [译]jclass和jobject 2012-09-18 15:02:58|  分类: Android |字号 订阅   jclass和jobject的迷惑第一次使用JNI,实例引用(jobject) ...

  6. IIS 7.5+FCK编辑器+burp suite神器拿webshell

    本人小菜一枚,大牛勿喷 看图: 一个越南狗的网站,看了看好多人来过哦,估计都是在这跪下了,试了好多别人上传滴都不行,看了看是IIS7.5,难怪都卡在这里了,于是小编直接上神器Burp Suite- 截 ...

  7. 019sys模块

    为了和python解释器交互,控制台执行脚本后面添加变量 import  sysprint(sys.argv) def  post():    print('upload')def  download ...

  8. NET Core Web API下事件驱动型架构CQRS架构中聚合与聚合根的实现

    NET Core Web API下事件驱动型架构在前面两篇文章中,我详细介绍了基本事件系统的实现,包括事件派发和订阅.通过事件处理器执行上下文来解决对象生命周期问题,以及一个基于RabbitMQ的事件 ...

  9. 编码 Unicode utf-8

    编码的发展史: 一开始计算机只在美国使用.8位的字节可以组合出256种不同的状态.他们将0到32种状态规定为”控制码“,后来又用其中32号以后的状态表示空格.标点符号.数字和大小写字母.这样一直编到了 ...

  10. 牛客网多校训练第一场 A - Monotonic Matrix(Lindström–Gessel–Viennot lemma)

    链接: https://www.nowcoder.com/acm/contest/139/A 题意: 求满足以下条件的n*m矩阵A的数量模(1e9+7):A(i,j) ∈ {0,1,2}, 1≤i≤n ...