Created
November 22, 2018 03:50
-
-
Save ApolloZhu/5031907931fc6bc031a7013bd8075029 to your computer and use it in GitHub Desktop.
Get the first 250 or 1000 followers of a user on bilibili
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let id: Int = /*Replace with your bilibili user id*/ | |
// You can simply copy paste the entire cookie, but the following is the minimum: | |
// If id is different from DedeUserID (i.e. you don't own such account), this doesn't matter | |
let cookie = "DedeUserID=XXXX;DedeUserID__ckMd5=XXXXXXXXXXXXXXXX;SESSDATA=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;" | |
/////////////////////////////////////// | |
// Code // | |
/////////////////////////////////////// | |
import Foundation | |
struct User: Codable { | |
let mid: Int | |
let uname: String | |
} | |
struct Wrapper: Codable { | |
let data: Data | |
struct Data: Codable { | |
let list: [User] | |
let total: Int | |
} | |
} | |
func fetchFollowersOfUser( | |
_ id: Int = id, page: Int, pageSize: Int = 50, | |
then process: @escaping (_ total: Int, _ list: [User]) -> Void | |
) { | |
let url = URL(string: "http://api.bilibili.com/x/relation/followers?vmid=\(id)&pn=\(page)&ps=\(pageSize)") | |
var request = URLRequest(url: url!) | |
request.addValue(cookie, forHTTPHeaderField: "Cookie") | |
URLSession.shared.dataTask(with: request) { (data, _, error) in | |
guard let data = data else { fatalError(error?.localizedDescription ?? "Failed") } | |
do { | |
let wrapped = try JSONDecoder().decode(Wrapper.self, from: data) | |
process(wrapped.data.total, wrapped.data.list) | |
} catch { | |
print(String(data: data, encoding: .utf8)!) | |
process(0, []) | |
} | |
}.resume() | |
} | |
var allFollowers = [User]() | |
var page = 1 | |
func run() { | |
fetchFollowersOfUser(page: page) { (total, list) in | |
if list.count == 50 { | |
allFollowers += list | |
page += 1 | |
print("\(allFollowers.count)/\(total)") | |
run() | |
} else { | |
try! allFollowers.sorted { | |
$0.mid < $1.mid | |
}.reduce("") { | |
"\($0)\($1.mid) \($1.uname)\n" | |
}.write(toFile: "\(id).txt", atomically: true, encoding: .utf8) | |
exit(0) | |
} | |
} | |
} | |
run() | |
RunLoop.current.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment