【瞎扯】Instagram爬虫编写过程 附源码

共计 4672 个字符,预计需要花费 12 分钟才能阅读完成。

前言

昨天把ins上一个美图博主的图片爬了下来,@zeewipark 就是Ta(不知道性别...)啦~

为啥要爬下来可以看下昨天的文章链接:https://b.julym.com/share/719.html

昨天用易语言写的爬虫,今天早上用java写了出来,刚好分享出来还能水一篇文章 :tv39:

正文

首先,确定要爬的主页链接,以@zeewipark 为例,主页链接为:https://www.instagram.com/zeewipark/

打开后我们按下f12调开发者工具出来选择Network 开始抓包,刷新一下,鼠标直接点XHR分类(也就是XMLHttpRequest ),这样可以直接看到ins使用AJAX请求了哪些数据接口。

【瞎扯】Instagram爬虫编写过程 附源码

依次查看这几个请求的返回数据发现在这一个Get请求中返回了部分ta主页的图片url(链接)。

【瞎扯】Instagram爬虫编写过程 附源码

【瞎扯】Instagram爬虫编写过程 附源码

复制到浏览器访问发现可以显示出图片,但不是第一张,这时候仔细看看请求头的参数,除了query_hash外还附带了一串url编码过的json字符串。

【瞎扯】Instagram爬虫编写过程 附源码

id应该是这个博主的一个id,看到first是12,可能指的就是从哪里开始返回数据,12就是从第12张图后开始返回,还有一个after,看起来像是base64编码后的数据,这时候不要着急,继续往下滑网页(Instagram一次只加载一部分数据),

在加载出新图片的同时,调试工具再次出现了?query_hash_d496e开头的请求,那么就证明图片确实是从这一个接口请求出来的。但这时候发现请求参数中的after出现了变化,其他没有变化。

【瞎扯】Instagram爬虫编写过程 附源码

【瞎扯】Instagram爬虫编写过程 附源码

前后对比一下这两个请求返回的数据,发现了第一次请求返回中的json字符串中有这一段数据,等等,这不是对应了第二次返回的after参数吗?

【瞎扯】Instagram爬虫编写过程 附源码

【瞎扯】Instagram爬虫编写过程 附源码

再根据这些参数名 page_info has_next_page after  end_currsor的设定,可以判断出after参数应该是一个位置标识,请求这个位置标识之后的数据。query_hash 应该是一个用博主的id之类的加密出来的一个特定值(因为我昨天抓包到今天抓包 这个参数不变),而count刚好对应上这个博主的文章数量。

【瞎扯】Instagram爬虫编写过程 附源码

那么有了这些数据的话就可以开始理清思路写代码了。

分析返回的json字符串得知每次返回的图片只有12张,那么560张总共需要返回560/12=46.6≈47次。

那就写一个for循环,循环请求这个URL47次,每一次请求保存下after的值给下一次请求做参数。然后在for循环中再写一个for循环遍历json里的数组 取出12张图片的url再保存下来。

以下代码需要一个http请求类一次一个json解析类(第三方类 需要网上下载后引入项目)

Java 源代码以及Http请求类、Json类下载地址:点我下载

易语言 源代码:点我下载

易语言的用了本地的socks5代理,记得自行修改或去掉。

python用request包就可以了

php直接用自带的file_get_contents就行 或者 curl

(当然 如果写成多线程的话会快很多倍)

效果图:

【瞎扯】Instagram爬虫编写过程 附源码

具体代码如下:


package httprequest;
import java.io.UnsupportedEncodingException;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class instagram {
public static void main(String[] args) throws Exception {
// TODO 自动生成的方法存根
String str;//保存每次请求接口返回的数据
int i,j,k = 0;//i,j用于循环体记录,k用来给图片做文件名
String variables;//保存位置标识参数的变量
JSONObject json = null;//json对象 解析json字符串
variables = "%7B%22id%22%3A%2214847010%22%2C%22first%22%3A0%2C%22after%22%3A%22QVFEUEtZMnhHQmhicHNmVVN0ejVzU1dIamtOWWVSb0kyVmx0bmlzdjVWcEx3bmhMLWtoZTF0bkNDWm91WGRxbEhnZlh3M3E1bXJXM0ladWVxdVRnQ3AxYg%3D%3D%22%7D";
//第一次请求的after参数
String json1 = "{\"id\":\"14847010\",\"first\":12,\"after\":\"";//有斜杠是因为json字符串里有"号,而java使用"包裹字符串,所以需要使用\斜杠把"转义为原来的字符含义
String json2 = "\"}";//json1和json2用于给after参数拼接json字符串
String url = "https://www.instagram.com/graphql/query/?query_hash=d496eb541e5c789274548bf473cc553e&variables=";//设置请求的url
HttpRequest http = new HttpRequest();//实例化一个http类
for (j=0;j<47;j++) {//开始循环47次,因为总共560张图,每次返回12张,需要循环560/12=46.66≈47次
str = http.sendGet(url+variables);//发起Get请求,将variables拼接至url后
json = new JSONObject(str);//json解析返回的结果
JSONObject json3 = json.getJSONObject("data");
json3 = json3.getJSONObject("user");
json3 = json3.getJSONObject("edge_owner_to_timeline_media");
json3 = json3.getJSONObject("page_info");
//一步一步解析出end_cursor(也就是after参数的值),用作下一次请求的参数
variables = java.net.URLEncoder.encode(json1 + json3.getString("end_cursor")+json2,"UTF-8");//java.net.URLEncoder.encode为拼接好的variables参数进行url编码
json3 = json.getJSONObject("data");
json3 = json3.getJSONObject("user");
json3 = json3.getJSONObject("edge_owner_to_timeline_media");
JSONArray edges = json3.getJSONArray("edges");
//解析出包含图片url的json数组并复制给edges
for(i=0;i
正文完
 
Swaggy Macro
版权声明:本站原创文章,由 Swaggy Macro 2020-04-02发表,共计4672字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)