Skip to content

Commit 10bbdae

Browse files
committed
add user's tagged posts' scraping
1 parent 827f3d4 commit 10bbdae

File tree

4 files changed

+65
-14
lines changed

4 files changed

+65
-14
lines changed

src/api/api.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,14 @@ export class Post extends Instagram<TSinglePost> {
9292
// But usage with fullAPI option brings an extra post, because of scrapeDefaultPosts
9393
// So we force it to be disabled
9494
options.fullAPI = false;
95-
super("https://instagram.com/p/", ids[0], "", "", options, SinglePost);
95+
super(
96+
"https://instagram.com/p/[id]",
97+
ids[0],
98+
"",
99+
"",
100+
options,
101+
SinglePost,
102+
);
96103
this.ids = ids;
97104
}
98105

@@ -122,18 +129,18 @@ export function createApi(
122129
): Search;
123130
export function createApi(type: "post", id: string[], options?: IOptions): Post;
124131
export function createApi(
125-
type: "hashtag" | "user",
132+
type: "hashtag" | "user" | "tagged",
126133
id: string,
127134
options?: IOptionsRegular | IOptionsRegularPlugins<InstagramPostClass>,
128135
): InstagramPostClass;
129136
export function createApi(
130-
type: "hashtag" | "user",
137+
type: "hashtag" | "user" | "tagged",
131138
id: string,
132139
options?: IOptionsFullApi | IOptionsFullApiPlugins<InstagramFullPostClass>,
133140
): InstagramFullPostClass;
134141

135142
export function createApi(
136-
type: "hashtag" | "user" | "post" | "search",
143+
type: "hashtag" | "user" | "tagged" | "post" | "search",
137144
id: string | string[],
138145
options?: IOptions,
139146
): Post | InstagramPostClass | InstagramFullPostClass | Search {
@@ -149,6 +156,9 @@ export function createApi(
149156
case "user":
150157
ClassConstructor = User;
151158
break;
159+
case "tagged":
160+
ClassConstructor = Tagged;
161+
break;
152162
}
153163
if (options.fullAPI) {
154164
return new ClassConstructor<TFullApiPost>(id as string, options);
@@ -161,7 +171,7 @@ export function createApi(
161171
*/
162172
export class Hashtag<T> extends Instagram<T> {
163173
constructor(id: string, options: IOptions = {}) {
164-
const endpoint = "https://instagram.com/explore/tags/";
174+
const endpoint = "https://instagram.com/explore/tags/[id]";
165175
const pageQuery = "data.hashtag.edge_hashtag_to_media.page_info";
166176
const edgeQuery = "data.hashtag.edge_hashtag_to_media.edges";
167177
super(
@@ -180,7 +190,7 @@ export class Hashtag<T> extends Instagram<T> {
180190
*/
181191
export class User<T> extends Instagram<T> {
182192
constructor(id: string, options: IOptions = {}) {
183-
const endpoint = "https://instagram.com/";
193+
const endpoint = "https://instagram.com/[id]";
184194
const pageQuery = "data.user.edge_owner_to_timeline_media.page_info";
185195
const edgeQuery = "data.user.edge_owner_to_timeline_media.edges";
186196
super(
@@ -193,3 +203,22 @@ export class User<T> extends Instagram<T> {
193203
);
194204
}
195205
}
206+
207+
/**
208+
* An Instagram user's tagged posts API wrapper
209+
*/
210+
export class Tagged<T> extends Instagram<T> {
211+
constructor(id: string, options: IOptions = {}) {
212+
const endpoint = "https://instagram.com/[id]/tagged";
213+
const pageQuery = "data.user.edge_user_to_photos_of_you.page_info";
214+
const edgeQuery = "data.user.edge_user_to_photos_of_you.edges";
215+
super(
216+
endpoint,
217+
id,
218+
pageQuery,
219+
edgeQuery,
220+
options,
221+
getPageValidator(options),
222+
);
223+
}
224+
}

src/api/instagram.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export class Instagram<PostType> extends EventEmitter {
173173
super();
174174
this.id = id;
175175
this.postIds = new PostIdSet();
176-
this.url = endpoint + id;
176+
this.url = endpoint.replace("[id]", id);
177177

178178
options = Instagram.defaultOptions(options);
179179
this.total = options.total;

src/cli.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,24 @@ function buildParser(args, callback) {
6666
await spawn(handleArgs);
6767
callback();
6868
})
69-
.command("user [id]", "Scrape a user", {}, async (handleArgs) => {
70-
await spawn(handleArgs);
71-
callback();
72-
})
69+
.command(
70+
"user [id]",
71+
"Scrape a users posts",
72+
{},
73+
async (handleArgs) => {
74+
await spawn(handleArgs);
75+
callback();
76+
},
77+
)
78+
.command(
79+
"tagged [id]",
80+
"Scrape a user's tagged posts",
81+
{},
82+
async (handleArgs) => {
83+
await spawn(handleArgs);
84+
callback();
85+
},
86+
)
7387
.command(
7488
"post [ids]",
7589
"Scrape a comma-separated list of posts",

tests/test.spec.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {Overrides, Request} from "puppeteer";
33
import * as winston from "winston";
44
import {createApi, IPlugin} from "..";
55
import {plugins} from "..";
6-
import {IPluginContext} from "../plugins/plugin";
6+
import {IPluginContext} from "../plugins";
77
import {IOptions, IOptionsFullApi} from "../src/api/api";
88
import {FakePage, IFakePageOptions} from "./__fixtures__/FakePage";
99
import {QuickGraft} from "./__fixtures__/QuickGraft";
@@ -70,6 +70,7 @@ describe("Library Classes", () => {
7070
const objects = {
7171
hashtag: createApi("hashtag", hashtags[0], libraryTestOptions),
7272
post: createApi("post", posts, libraryTestOptions),
73+
tagged: createApi("tagged", users[0], libraryTestOptions),
7374
user: createApi("user", users[0], libraryTestOptions),
7475
};
7576

@@ -94,6 +95,7 @@ describe("Library Functions", () => {
9495
libraryTestOptions,
9596
).generator(),
9697
post: createApi("post", posts, libraryTestOptions).generator(),
98+
tagged: createApi("tagged", users[0], libraryTestOptions).generator(),
9799
user: createApi("user", users[0], libraryTestOptions).generator(),
98100
};
99101

@@ -118,6 +120,7 @@ describe("Full API", () => {
118120
const generators = {
119121
hashtag: createApi("hashtag", hashtags[0], fullApiOption).generator(),
120122
post: createApi("post", posts, fullApiOption).generator(),
123+
tagged: createApi("tagged", users[0], fullApiOption).generator(),
121124
user: createApi("user", users[0], fullApiOption).generator(),
122125
};
123126

@@ -134,11 +137,15 @@ describe("Full API", () => {
134137
});
135138

136139
class ApiTestConditions {
137-
public api: "hashtag" | "user";
140+
public api: "hashtag" | "user" | "tagged";
138141
public ids: string[];
139142
public sizes: number[];
140143

141-
constructor(api: "hashtag" | "user", ids: string[], sizes: number[]) {
144+
constructor(
145+
api: "hashtag" | "user" | "tagged",
146+
ids: string[],
147+
sizes: number[],
148+
) {
142149
this.api = api;
143150
this.ids = ids;
144151
this.sizes = sizes;
@@ -152,6 +159,7 @@ const endpoints: ApiTestConditions[] = [
152159
smallSize,
153160
]),
154161
new ApiTestConditions("user", users, [mediumSize, smallSize]),
162+
new ApiTestConditions("tagged", users, [mediumSize, smallSize]),
155163
];
156164

157165
test("Instagram API limits", async () => {

0 commit comments

Comments
 (0)