instagram 爬虫 2021,下载可用_ins爬虫工具_zzqtty的博客-程序员秘密

技术标签: 爬虫  instagram  

1.爬虫选择

由于我是java开发人员,所以首先选择的是java爬虫。但是java做爬虫不太友好。之前我是用的nutch2.2.1,爬取的newsbrak和vmate,但是这个工具比较老。最近需要爬取instagram的图片的视频,首先排除了nutch因为需要登录和ajax动态加载数据。然后尝试了下webmagic,但是账号被提示封禁。在尝试了许多网上的方法后,找到了解决方案。大部分实现方案都是python,还有的使用js实现。但是都没有被模块化,使用不方便。还有的项目比较老,现在运行报错。

2.java实现

链接 https://b.julym.com/study/720.html

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<edges.length();i++) {//开始循环 edges.length()为取这个数组的成员数量,文章里说了每次只返回12张图片链接,但保险起见还是循环成员总数量的次数
JSONObject tempobj = (JSONObject) edges.get(i);//取到图片的json对象复制给临时Json类 tmpobj
JSONObject tempobj1 = tempobj.getJSONObject("node");//因为图片在node对象,所以去出node对象并复制给临时json对象 tempobj1
JSONArray temparr = tempobj1.getJSONArray("display_resources");//取出包含图片url的数组,一般有三个成员,因为图片有三种大小
tempobj = (JSONObject) temparr.get(2);//直接去第三个,因为是最清晰的
System.out.println(tempobj.getString("src"));//控制台输出一下url链接
k=k+1;//记录一下是第几张图片,好给图片命名
GetUrlPic(tempobj.getString("src"),"images\\"+k+".jpg");//调用geturlpic方法 将图片保存至当前工作目录下的images文件夹(事先创建好)
}
}
//System.out.println();
}
public static void GetUrlPic(String url,String filename) throws Exception {
URL url1 = new URL(url);
//打开链接
HttpURLConnection conn = (HttpURLConnection)url1.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
//通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(inStream);
//new一个文件对象用来保存图片,默认保存当前工程根目录
File imageFile = new File(filename);
//创建输出流
FileOutputStream outStream = new FileOutputStream(imageFile);
//写入数据
outStream.write(data);
//关闭输出流
outStream.close();
}
public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=inStream.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
}

这个是唯一能运行的java代码,但是有部分错误。需要的参数有点多,和我预期的有点大。但是思路正确,模拟请求调用,这个基本是主流实现方案。

https://github.com/postaddictme/instagram-java-scraper

这个是模块化的,但是我搭建环境后,运行失败,估计还是代码太老了,没有更新

3.python实现

python在写爬虫方面确实有很大优势。

感谢 https://github.com/arc298/instagram-scraper

这个最终采用的方案。cmd可以运行,需要设置外网。搭建好python环境后,运行直接成功。python环境的搭建可以下个软件,直接安装,然后就是3.7了。Linux大部分自带的都是2.7,需要升级,很麻烦。

To install instagram-scraper:

$ pip install instagram-scraper

To update instagram-scraper:

$ pip install instagram-scraper --upgrade

Alternatively, you can clone the project and run the following command to install: Make sure you cd into the instagram-scraper-master folder before performing the command below.

$ python setup.py install

Usage

To scrape a user's media:

$ instagram-scraper <username> -u <your username> -p <your password> 

后面再根据自己的业务需求和java结合。

登录后,直接输入博主名称,即可下载博主所有图片的视频。

4.设置外网 注意:

感谢文章 https://blog.csdn.net/baidu_39372836/article/details/96373719

1、设置cmd代理

终端输入:
set http_proxy=http://127.0.0.1:1080
set https_proxy=http://127.0.0.1:1080

终端输入:
set http_proxy=http://127.0.0.1:1080
set https_proxy=http://127.0.0.1:1080

坑点

不要输入ping www.google.com ping的协议不是https,也不是https,是ICMP协议。

终端输入:
curl -vv http://www.google.com
查看响应数据即可,有则说明成功
 

instagram 访问都是翻墙,需要使用代理网上的说法都是 set ,然后我就ping,一直以为设置错误。写文章能不能写全点,全是一半!!!

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zzqtty/article/details/115179815

智能推荐

编译ubi工具_sudo mkdir tools_qq_28219531的博客-程序员秘密

一.下载源代码。1. sudo wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.03.tar.gz2.sudo wget http://zlib.net/zlib-1.2.11.tar.gz3.sudo wget http://debian.mirror.inra.fr/debian/pool/main/m/mtd-utils...

学习笔记:java并发编程学习之初识Concurrent_weixin_33772645的博客-程序员秘密

一、初识Concurrent第一次看见concurrent的使用是在同事写的一个抽取系统代码里,当时这部分代码没有完成,有许多的问题,另一个同事接手了这部分代码的功能开发,由于他没有多线程开发的经验,所以我就一起帮着分析。最开始看到这个时很烦燥啊,因为自己接触java时间很短,连synchronized都不知道怎么用呢,突然发现有这么个复杂的东西。当时就只好开始学习吧,毕竟是使用嘛,第一目的就...

用esp8266实现远程空调控制(一)_esp8266控制空调_布衣而已的博客-程序员秘密

实现功能:实现远程控制宿舍空调的启停,定时和其他操作;材料清单:esp8266(EP_01s),红外发射模块,烧录器。编程软件:Ardunio IDE初步想法:用esp8266建立一个WebServe,通过网页传送相关指令到esp8266,再通过esp8266操作红外模块,实现对空调的控制。代码一:搭建webServe/大纲:#include&lt;ESP8266WiFi.h&gt;#include &lt;ESP8266WebServer.h&gt;#include &lt;ESP8

手把手教你写一个抢讲座的脚本_抢讲座脚本_WeichaoZhu的博客-程序员秘密

利用js脚本来帮你抢到一个表单提交类型的各种活动,这里以讲座为例~准备注册一个麦克表单创建一个自己的表单数据探索首先自己提交一个表单,同时打开f12中的network,看一看自己提交的东西包含了什么。比如这里我们发现了d这个对象之后我们尝试着按照它这种格式,自己提交一下,看看能不能成功。这里我选用了restlet这个工具。可以发现,成功了o(* ̄▽ ̄*)o分析我们来仔细研究下这个表单中提交的这个数...

python+selenium+chrome,class name定位元素时,class属性值带有空格报错_元素定位class name有空格_代码信徒的博客-程序员秘密

场景:python+selenium+chrome,class name定位元素时,class属性值带有空格会报错:selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".fm has-soutu"}解决方法:用小数点:. 代替空格如:fm has-soutu.

后缀自动机概念的温习_weixin_30393907的博客-程序员秘密

觉得对于一个数据结构充分的学会使用,一定要对它的构成部分和定义概念有很充分很全面的了解.所以我觉得的一种温习的最好方式就是:明晰概念-&gt;分析运用这样的层次.概念的明晰确实是十分有用的,它既是理解他人算法的必要前提,也是你在看到题目后可以有创新想法的重要基础.下面这篇文章主要是写给笔者自己看的...所以逻辑有点混乱是因为写的顺序不是这样一路下去的...2331.状态...

随便推点

html中使用vant的van-list列表懒加载_van-list有懒加载吗_hy3528的博客-程序员秘密

使用van-list标签将需要进行懒加载的内容包住 &lt;van-list class="activity" v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad"&gt; &lt;div class="activity_cont" v-for="(item,index) in activitylist" :key="index"&gt;

spry菜单栏(一)_weixin_30268921的博客-程序员秘密

spry菜单栏使用教程关于 Spry 框架Spry 框架是一个 JavaScript 库,Web 设计人员使用它可以构建能够向站点访问者提供更丰富体验的 Web 页。有了 Spry,就可以使用 HTML、CSS 和极少量的 JavaScript 将 XML 数据合并到 HTML 文档中,创建构件(如折叠构件和菜单栏),向各种页面元素中添加不同种类的效果。在设计上,Spry 框架的标记非常简...

罗云彬Win32汇编_罗云彬汇编评价_白菜兔的博客-程序员秘密

今天看了下罗老师的Win32汇编,感觉跟DOS下汇编的确差别比较大。        感觉Win32汇编好像有高级语言的味道,实现方式是通过加载Windows的DLL库,程序书写方式也跟C语言比较相似,感觉更像的一点的通过汇编可以直接调用Windows的API接口,简单方便之时,感觉会不会Windows已经把核心给封装了,Win32汇编已经不能操作太底层的硬件了。        第一天看,发

ARP***原理与解决方法《二》_weixin_34174132的博客-程序员秘密

【故障现象】 当局域网内某台主机运行ARP欺骗的***程序时,会欺骗局域网内所有主机和路由器,让所有上网的流量必须经过病毒主机。其他用户原来直接通过路由器上网现在转由通过病毒主机上网,切换的时候用户会断一次线。切换到病毒主机上网后,如果用户已经登陆了服务器,那么病毒主机就会经常伪造断线的假像,那么用户就得重新登录服务器,这样病毒主机就可以盗号了。由于ARP欺骗的*...

IOS开发之旅-IOS常用数据结构NSArray、NSMutableArray、NSDictionary、NSMutableDictionary介绍..._weixin_30519071的博客-程序员秘密

NSArrayNSArray基本用法void arrayTest1(){ //数组初始化最后必须以nil结尾,表示数组元素结束 NSArray *array1 = [[NSArray alloc]initWithObjects:@"item0",@"item1",@"item2",@"item3",@"item4",nil]; ...

动态拼接SQL 语句_weixin_30510153的博客-程序员秘密

public T Get&lt;T&gt;(int id) { Type type = typeof(T); string columnStrings = string.Join(",", type.GetProperties().Select(p=&gt;string.Format("[{0}]")));...

推荐文章

热门文章

相关标签