国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

18143453325 在線咨詢 在線咨詢
18143453325 在線咨詢
所在位置: 首頁 > 營銷資訊 > 電子商務(wù) > 爬蟲爬取人人網(wǎng)社交數(shù)據(jù)(一)

爬蟲爬取人人網(wǎng)社交數(shù)據(jù)(一)

時(shí)間:2023-03-13 22:54:01 | 來源:電子商務(wù)

時(shí)間:2023-03-13 22:54:01 來源:電子商務(wù)

今天突然看到人人網(wǎng)的一個(gè)鏈接,想起前幾年可是很火的大學(xué)生社交網(wǎng)站,登錄自己的賬號進(jìn)去看后,發(fā)現(xiàn)這網(wǎng)站居然開始搞直播,不是之前那么單純的社交功能網(wǎng)站了,不過發(fā)現(xiàn)人人網(wǎng)的數(shù)據(jù)還挺有意思的,可以爬取到不認(rèn)識的人的社交資料,比如性別生日,所讀學(xué)校,好友列表的,這個(gè)數(shù)據(jù)可以拿來做一個(gè)社交關(guān)系網(wǎng)狀圖,甚至拿來檢驗(yàn)六度分隔理論,想想還有點(diǎn)小興奮,于是就開始研究怎么爬取人人網(wǎng)的數(shù)據(jù)。

首先看某個(gè)用戶的人人網(wǎng)主頁面 http://www.renren.com/494871890/profile , url中的494871890 很像是人人網(wǎng)用戶的id,后嘗試修改訪問其它頁面后得以證實(shí),也就是說我們只要能拿到一批用戶的id,然后去遍歷這些網(wǎng)頁,就能拿到這個(gè)用戶的一些社交信息。那么我們只要考慮兩個(gè)問題:

  1. 根絕某個(gè)用戶id可以拿到哪些用戶社交信息
  2. 如果獲取大量的用戶id
首先看第一個(gè)問題,我們能拿到用戶哪些信息

看上圖大紅色方框選定的地方,可以拿到用戶的 昵稱,就讀學(xué)校,性別,生日,居住地,主頁訪問次數(shù),好友列表 等信息,還有用戶的logo也是可以爬取下來的,這些信息應(yīng)該足以支撐我們做社交網(wǎng)絡(luò)的研究了。

再看第二個(gè)問題,如果和獲取大量的用戶id,看上圖紅色小紅色方框部分,每個(gè)用戶頁面都會展示用戶好友,那么這就很好辦了,根據(jù)一個(gè)用戶id獲取他的好友id,再根據(jù)他的好友id獲取更多的好友,也就是說我們只需要一個(gè)用戶的id(比如就是你的id),可以獲取到非常多的用戶id,假定平均每個(gè)人有100個(gè)好友,那么我們爬取你的好友數(shù)量是 100,你好友的好友是 100*100 = 10000 ,你好友的好友的好友 100*100*100 = 100w,這個(gè)數(shù)字就已經(jīng)非常大了。

大概的計(jì)劃有了,我們就可以開始找網(wǎng)站的接口了

打開 http://www.renren.com/494871890/profile ,使用控制臺選中我們要爬取的元素,就能看到實(shí)際上我們要爬取的數(shù)據(jù)都在一個(gè)id為 operate_area 的 div元素中,這就很好辦了,我們只要爬取到這個(gè)頁面的html然后再使用正則或者是 xpath將我們需要的元素爬取出來就可以了,但是這里得注意到,社交網(wǎng)站一般都會驗(yàn)證登錄的,嘗試了一下不加cookie果然是爬取不到用戶頁面的,果斷去找到登錄的Cookie,隨便找個(gè)請求報(bào)文找到Header中的Cookie,就是下圖紅框部分,隱私信息太多了,碼都打不過來。

然后我們就可以編寫http類了

首先寫個(gè)HttpUtil類用于訪問網(wǎng)頁代碼,post和get方法都需要

package http;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.HttpClient;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import util.RegexUtil;import java.util.*;/** * Created by on 2017/12/23. */public class HttpUtil { public String doGet(String url, Map<String, String> headers) { HttpClient httpClient; HttpGet httpGet; String result = null; try { httpClient = HttpClients.createDefault(); httpGet = new HttpGet(url); Iterator<Map.Entry<String, String>> it = headers.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); String key = entry.getKey(); String val = entry.getValue(); httpGet.addHeader(key, val); } HttpResponse response = httpClient.execute(httpGet); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, "utf8"); } } } catch (Exception ex) { System.out.println("http get失敗"); } return result; } public String doPost(String url, Map<String, String> params, Map<String, String> headers) { HttpClient httpClient; HttpPost httpPost; String result = null; try { httpClient = HttpClients.createDefault(); httpPost = new HttpPost(url); Iterator<Map.Entry<String, String>> it = headers.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); String key = entry.getKey(); String val = entry.getValue(); httpPost.addHeader(key, val); } Iterator iterator = params.entrySet().iterator(); List<NameValuePair> list = new ArrayList<NameValuePair>(); while (iterator.hasNext()) { Map.Entry<String, String> elem = (Map.Entry<String, String>) iterator.next(); list.add(new BasicNameValuePair(elem.getKey(), elem.getValue())); } if (list.size() > 0) { UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "utf8"); httpPost.setEntity(entity); } HttpResponse response = httpClient.execute(httpPost); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, "utf8"); } } } catch (Exception ex) { System.out.println("http post失敗"); } return result; } public static void main(String[] args) { HttpUtil util = new HttpUtil(); Map<String, String> headers = new HashMap<String, String>(); headers.put("Cookie", "你的cookie串"); String htmlStr = util.doGet("http://www.renren.com/494871890/profile", headers); Map<String,String> userInfo = RegexUtil.groupUserInfo(htmlStr); System.out.println(userInfo); }}

同時(shí)拉取到的是整個(gè)網(wǎng)頁的代碼,所以我們要使用正則或者xpath選擇到我們需要的元素,這里使用正則,編寫了一個(gè)正則的工具類RegexUtil

package util;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Created by on 2017/12/24. */public class RegexUtil { public static List<String> getValByReg(String str, String reg, int valueNum) { List<String> rets = null; Pattern p = Pattern.compile(reg); Matcher m = p.matcher(str); if (m.find()) { if (m.groupCount() == valueNum) { rets = new ArrayList<String>(); for (int i = 1; i <= valueNum; i++) rets.add(m.group(i)); } } return rets; } /* * 獲取用戶標(biāo)題欄消息工具 * **/ public static Map<String, String> groupUserInfo(String htmlStr) { Map<String, String> retMap = new HashMap<String, String>(); try { String infoReg = "(<div class=/"tl-information/"[//s//S]+</div>)"; //獲取到存儲用戶信息的div List<String> rets = RegexUtil.getValByReg(htmlStr, infoReg, 1); if (rets == null || rets.size() < 1) { return retMap; } // 將div中的信息匹配出來 String div = rets.get(0).replace("/n", ""); Pattern p = Pattern.compile("<li class=/"(.*?)/">(.*?)</li>"); Matcher m = p.matcher(div); while (m.find()) { String attr = m.group(1); String value = m.group(2).replaceAll("(<span>|</span>| )", ""); retMap.put(attr, value); } } catch (Exception e) { return retMap; } return retMap; }}于是運(yùn)行上面httpUtil中的主類方法我們可以輸出的結(jié)果就是

{birthday=女生,二月十二日, hometown=來自河南商丘市, address=現(xiàn)居重慶, school=就讀于重慶郵電大學(xué)}這就是說我們已經(jīng)有了一個(gè)可以根據(jù)id拿到用戶主頁標(biāo)題欄信息的工具了

為了之后存儲數(shù)據(jù)庫方便,我們預(yù)先把用戶的bean類建好

package renren;import java.util.Set;/** * Created by on 2017/12/24. */public class User { private Stringd renrenId; // 人人id private String renrenName; // 人人昵稱 private String renrenInfo; //人人標(biāo)題欄信息 private int visitTime; //該人主頁被訪問次數(shù) private Set<String> allFriendsId; // 該人的所有好友人人id public User() { } public User(String renrenId, String renrenName, String renrenInfo, int visitTime, Set<String> allFriendsId) { this.renrenId = renrenId; this.renrenName = renrenName; this.renrenInfo = renrenInfo; this.visitTime = visitTime; this.allFriendsId = allFriendsId; } public String getRenrenId() { return renrenId; } public void setRenrenId(String renrenId) { this.renrenId = renrenId; } public String getRenrenInfo() { return renrenInfo; } public void setRenrenInfo(String renrenInfo) { this.renrenInfo = renrenInfo; } public int getVisitTime() { return visitTime; } public void setVisitTime(int visitTime) { this.visitTime = visitTime; } public String getRenrenName() { return renrenName; } public void setRenrenName(String renrenName) { this.renrenName = renrenName; } public Set<String> getAllFriendsId() { return allFriendsId; } public void setAllFriendsId(Set<String> allFriendsId) { this.allFriendsId = allFriendsId; } @Override public String toString() { return String.format("%s---%s---%s---%d", renrenId, renrenName, renrenInfo, visitTime); }}可以看到我們再bean中還定義了 用戶昵稱,用戶主頁面訪問次數(shù),好友id集合的字段,好友id集合獲取方式會在后面介紹,有點(diǎn)小復(fù)雜

先看看獲取用戶昵稱 用戶主頁面訪問次數(shù) 的獲取,都在 之前的 RegexUtil中

package util;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Created by on 2017/12/24. */public class RegexUtil { /* * 獲取用戶昵稱信息 * **/ public static String groupUsername(String htmlStr) { String nameReg = "<title>人人網(wǎng) - (.*)</title>"; List<String> rets = RegexUtil.getValByReg(htmlStr, nameReg, 1); if (rets != null && rets.size() > 0) return rets.get(0); return null; } //獲取用戶主頁面訪問次數(shù) public static int groupVisitTime(String htmlStr){ htmlStr.replace("/n",""); String visitTimeReg = "(<div id=/"footprint-box/"[//s//S]*/h5>)"; List<String> rets = RegexUtil.getValByReg(htmlStr, visitTimeReg, 1); if(rets!=null && rets.size()>0){ String div = rets.get(0).replace("/n",""); String visitTime = div.replaceAll(".*最近來訪.*?(//d+).*","$1"); if(visitTime.matches("//d+")) return Integer.parseInt(visitTime); } return 0; }}現(xiàn)在我們能拿到的信息有 用戶id,用戶昵稱,用戶標(biāo)題欄信息(地址,大學(xué)等),主頁訪問次數(shù) , 編寫一個(gè)主類來試一下

package http;import net.sf.json.JSONObject;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.HttpClient;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import renren.User;import util.RegexUtil;import java.util.*;/** * Created by on 2017/12/23. */public class Test { public static void main(String[] args) { HttpUtil util = new HttpUtil(); Map<String, String> headers = new HashMap<String, String>(); // Cookie headers.put("Cookie","你的cookie"); String renrenId ="494871890"; String htmlStr = util.doGet("http://www.renren.com/"+renrenId+"/profile", headers); //獲取用戶信息 Map<String,String> userInfo = RegexUtil.groupUserInfo(htmlStr); JSONObject jsonObj = JSONObject.fromObject(userInfo); String renrenInfo = jsonObj.toString(); //獲取用戶姓名 String userName = RegexUtil.groupUsername(htmlStr); //獲取用戶主頁面訪問次數(shù) int visitTime= RegexUtil.groupVisitTime(htmlStr); User user = new User(renrenId,userName,renrenInfo,visitTime,null); System.out.println(user); }}輸出結(jié)果為

494871890---李瑤玉---{"birthday":"女生,二月十二日","hometown":"來自河南商丘市","address":"現(xiàn)居重慶","school":"就讀于重慶郵電大學(xué)"}---62那么我們根據(jù)一個(gè)id獲取到用戶信息并且填入bean已經(jīng)可以成功了,后續(xù)會講到

如何獲取好友id列表,源源不斷的獲取到用戶id,并且爬取信息入庫,最后庫中的數(shù)據(jù)基本如下所示

包含 用戶id ,昵稱,概括信息,主頁訪問次數(shù),好友列表,以及存儲每個(gè)用戶的頭像圖片

當(dāng)爬取到一定的數(shù)據(jù)之后(大概7000條),使用 gephi進(jìn)行圖像繪制,gephi可以繪制網(wǎng)絡(luò)關(guān)系圖,我們只要提供 點(diǎn),邊的關(guān)系即可,我們這里的點(diǎn)就是 各個(gè)用戶的renren昵稱(如果沒有昵稱可以用id替代) , 我們這里的邊是 具有好友關(guān)系的兩個(gè)人的id , 對我們庫中的數(shù)據(jù)進(jìn)行簡單的處理后,可以得到點(diǎn)的信息

id 為renren_id,Label 為人名,對于沒有爬取到的人名用佚名代替

得到邊的信息如下

source 為邊起始人人 id

target 為結(jié)束的人人 id

Itype為連線類型,為無向邊

id是該邊的id

weight為權(quán)重,即邊的粗細(xì)

導(dǎo)入點(diǎn)數(shù)據(jù)到gephi

導(dǎo)入邊數(shù)據(jù)到gephi

最后生成一個(gè)關(guān)系圖

可以到看很多聚集的點(diǎn)就是一個(gè)人的所有好友,這個(gè)人同時(shí)連接了很多點(diǎn)

這個(gè)圖只是用了幾千個(gè)點(diǎn)和邊,即幾千個(gè)人的聯(lián)系,因爬取的數(shù)據(jù)量相比gephi的計(jì)算而言過多,無法將圖形繪制圖來,過多cpu會發(fā)燙,目前只能達(dá)到這個(gè)量級的繪制了。

關(guān)鍵詞:數(shù)據(jù),社交,爬蟲

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉