Eng:
https://rentry.co/vh3py
Spanish:
https://rentry.co/agr95
Japanese:
https://crieit.net/posts/Bank-6249a7b59dfd9
À propos de ce qui était une banque de mangas.
La "mangabank | Banque de manga" a disparu.
Il est devenu un nouveau site illégal appelé 13dl.me, mais comme le style de lecture en ligne a été abandonné et est devenu un type de portée de téléchargement, cet article a également été mis à jour sur le tableau, comme une nouvelle étape.
Ancienne conseil d'administration
Jusqu'à ce que Mangabank disparaît
https://crieit.net/boards/manga-b
Eh bien, je me suis toujours demandé comment écrire JavaScript
, alors j'ai écrit un programme en JavaScript
en utilisant Node.js
pour voir à quoi ressemble ce nouveau site illégal.
Cela m'a pris un certain temps parce que je ne connaissais pas la promesse, mais il avait plus de documentation JavaScript
que Nim
, donc il ne fallut pas longtemps avant que le programme ne fonctionne.
Installez Node.js
et installez Axios
, Cheerio
avec npm
Package Manager.
https://nodejs.org/
https://github.com/axios/axios#installing
https://cheerio.js.org/
Rf.https://rentry.co/i542t
Un module qu'Axios
demande HTTPS, il s'agit d'une valeur de retour de type de promesse et peut traiter réponse si le 'http request' réussit.
Cheerio
utilise du texte HTML comme objet et l'utilise comme sélecteur CSS.
Je l'ai utilisé comme Nokogiri
dans Ruby
, comme BueAtifulSoup4
à Python
, comme Goquery
in Go
, comme Nimquery
in Nim
.
Ces sélecteurs de commodité ont des utilisations similaires et sont différentes, donc si vous n'êtes pas habitué à ne pas pouvoir les utiliser correctement, sauf si vous les regardez attentivement, vous pouvez gérer avec des expressions régulières même si vous ne les utilisez pas, donc dans ce Cas c'est la même chose même si la langue est différente. Le style d'expression régulière standard peut être écrit de la même manière.
https://en.m.wikipedia.org/wiki/Regular_expression
Go
a également un module d'expression régulière de style perl
(PCRE), bien qu'il ne s'agisse pas d'une bibliothèque standard.
RE2 is a fast, safe, thread-friendly alternative to backtracking regular expression engines like those used in PCRE, Perl, and Python. It is a C++ library.
License
BSD-3-Clause license
https://github.com/google/re2/
1. Base
| const cheerio = require('cheerio'),
axios = require('axios');
// url = `https://13dl.me/`;
var url = `https://13dl.me/list/popular/`;
var counter = 0;
function recursive(url){
let temp_url = url;
axios.get(url)
.then((response) => {
if (response.status == 200){
let $ = cheerio.load(response.data);
$('a').each(function (i, e) {
let title = $(e).attr('title');
let link = $(e).attr('href');
if (title !== undefined){
let h = /^Home/.test(title),
po = /^Popular\s/.test(title),
p = /^Prev/.test(title),
pa = /^Page/.test(title),
n = /^Next/.test(title);
if (h || po || p || pa || n || title === ``){
//unless
} else {
counter++;
console.log(counter + `{` + title +`{` + link);
// console.log(counter,title);
// console.log(`____________________`);
}
}
if (title === `Next`){
url = link;
// recursive(url);
}
})
if (url !== temp_url){
recursive(url);
}
}
}).catch(function (e) {
console.log(e);
recursive(url);
});
}
recursive(url);
|
Quel genre de programme est, il énumère le contenu sur le site.
Il appelle la fonction de manière récursive, mais je ne savais pas comment l'écrire en Javascript, mais cela a fonctionné, alors enregistrons le contenu à lister dans la base de données SQLite
.
Si vous l'utilisez avec awk
, vous pouvez également créer des fichiers de base de données SQLite3
avec ce programme de base. Définissez-le sur csv avec le délimiteur {
, lisez csv avec SQLite3
et enregistrez-le, et ce sera un fichier de base de données.
https://rentry.co/i542t
Ruby
Si vous écrivez un code de programme Ruby
similaire à ceci,
| require 'nokogiri'
#require 'oga' # alternative Nokogiri
require 'open-uri'
url = 'https://13dl.me/list/popular/'
counter = 0
threads = []
def recursive(counter,url,threads)
html = URI.open(url).read
doc = Nokogiri::HTML.parse(html)
#doc = Oga.parse_html(html)
html = nil
doc.css('a').each do |x|
xx = x.attr('title')
if xx && xx !='' && xx !='Home' && xx !='Popular Manga' then
pa = /^Page/.match?("#{xx}")
pr = /^Prev/.match?("#{xx}")
unless pa | pr then
n = /^Next/.match?("#{xx}")
link = ''
if n then
link = x.attr('href')
threads << Thread.new do
recursive(counter,link,threads)
end
else
counter += 1
puts "#{counter} #{xx}"
end
end
end
end
doc = nil
end
recursive(counter,url,threads)
threads.each(&:join)
|
https://0bin.net/paste/nPAYOHOy#N-V7Dd8utGb++7bPyJReeWz6QolQ+P+BeEM1W6Cz2Hw
python
| #!python -m pip install requests beautifulsoup4
import requests,re
from bs4 import BeautifulSoup
from urllib.parse import urlsplit
url = 'https://13dl.me/list/popular/'
counter = 0
def scrape(url,counter):
next_url = ""
response = requests.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.content)
response.close()
xx = soup.find_all("a",title=True)
del soup
if xx:
for x in xx:
if (x['title'] != '' and x['title'] != "Home" and x['title'] != "Popular Manga"):
pa_tf = bool(re.search(r'^Page',x['title']))
p_tf = bool(re.search(r'^Prev',x['title']))
if (pa_tf == False and p_tf == False):
if (x['title'] != "Next"):
counter += 1
print(counter,x['title'])
thumnail_addr = x('img')[0]['src']
base_url = "{0.scheme}://{0.netloc}/".format(urlsplit(thumnail_addr))
print(base_url)#cloudflare
else:
next_url = x['href']
del xx
else:
response.close()
return next_url,counter
while(url != ""):
url, counter = scrape(url,counter)
|
recursive
https://rentry.co/5ibqk
while
https://rentry.co/ir4b3
Nim
while
https://rentry.co/856s2
threadpool ... Work in Progress
https://rentry.co/ze8f4
perl5
https://rentry.co/perl5_manga
Go
recursive
https://rentry.co/f55r8
while(for)
https://rentry.co/75gch
&sync.wait.Group{} ... Work in Progress
https://rentry.co/wikwa
counting contents , page | channel , sync.Mutex
https://rentry.co/o8fp4
Elixir
https://rentry.co/nzo6g
2. SQLite3
| const cheerio = require('cheerio'),
axios = require('axios');
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('13dlme0.db',(err) => {
if(err) {
return console.error(err.message);
}
console.log('Connect to SQLite database.');
});
db.serialize(() => {
db.run(`CREATE TABLE manga(id interger,title string,link string)`)
});
var url = `https://13dl.me/list/popular/`;
var counter = 0;
function recursive(url){
let temp_url = url;
axios.get(url)
.then((response) => {
if (response.status == 200){
let $ = cheerio.load(response.data);
$('a').each(function (i, e) {
let title = $(e).attr('title');
let link = $(e).attr('href');
if (title !== undefined){
let h = /^Home/.test(title),
po = /^Popular\s/.test(title),
p = /^Prev/.test(title),
pa = /^Page/.test(title),
n = /^Next/.test(title);
if (h || po || p || pa || n || title === ``){
//unless
} else {
counter++;
// console.log(counter + ` ** ` + title + ` ** ` + link);
db.run(`insert into manga(id,title) VALUES(?,?)`,[counter,title]);
console.log(counter,title);
console.log(`____________________`);
}
}
if (title === `Next`){
url = link;
}
})
if (temp_url != url){
recursive(url);
};
}
}).catch(function (e) {
console.log(e);
recursive(url);
});
}
recursive(url);
|
db.close ()
Je n'ai pas.
Comment dois-je db.close ()
?
3. SQLite3 + db.close()
| const cheerio = require('cheerio'),
axios = require('axios');
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('13dlme_test1-1.db',(err) => {
if(err) {
return console.error(err.message);
}
console.log('Connect to SQLite database.');
});
db.serialize(() => {
db.run(`CREATE TABLE manga(id interger,title string,link string)`)
});
;
var url = `https://13dl.me/list/popular/`;
var counter = 0;
function recursive(url){
const temp_url = url;
const promise1 = axios.get(url)
const promiseData1 = promise1.then((response) => {
if (response.status == 200){
let $ = cheerio.load(response.data);
$('a').each(function (i, e) {
const title = $(e).attr('title');
const link = $(e).attr('href');
if (title !== undefined){
const h = /^Home/.test(title),
po = /^Popular\s/.test(title),
p = /^Prev/.test(title),
pa = /^Page/.test(title),
n = /^Next/.test(title);
if (h || po || p || pa || n || title === ``){
//unless
} else {
counter++;
// console.log(counter + ` ** ` + title + ` ** ` + link);
db.serialize(() => {
db.run(`insert into manga(id,title) VALUES(?,?)`,[counter,title]);
});
console.log(counter,title);
console.log(`____________________`);
}
}
if ((title === `Next`) && (link != undefined)){
url = link;
}
})
} else {
console.log(response);
}
if (temp_url !== url){
return recursive(url);
// `:keep going:`;
} else {
console.log('Close SQLite database.');
return `:stop:`;
}
}).catch(function (e) {
console.log(e);
});
Promise.all([promiseData1]).then((value) => {
if (value[0] === `:stop:`){
db.close((err) => {
if(err) {
console.error(err.message);
}
});
}
});
}
recursive(url);
|
Avez-vous fait db.close()
?
4. async/await
| const cheerio = require('cheerio'),
axios = require('axios');
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('13dlme_test2.db',(err) => {
if(err) {
return console.error(err.message);
}
console.log('Connect to SQLite database.');
});
db.serialize(() => {
db.run(`CREATE TABLE manga(id interger,title string,link string)`)
});
var url = `https://13dl.me/list/popular/`;
var counter = 0;
const recursive = async (url) => {
console.log(url);
const temp_url = url;
try {
const {data} = await axios.get(url);
const $ = cheerio.load(data)
$('a').each(function (i, e) {
const title = $(e).attr('title');
const link = $(e).attr('href');
if (title !== undefined){
const h = /^Home/.test(title),
po = /^Popular\s/.test(title),
p = /^Prev/.test(title),
pa = /^Page/.test(title),
n = /^Next/.test(title);
if (h || po || p || pa || n || title === ``){
//unless
} else {
counter++;
// console.log(counter + ` ** ` + title + ` ** ` + link);
db.run(`insert into manga(id,title) VALUES(?,?)`,[counter,title]);
console.log(counter,title);
console.log(`____________________`);
}
}
if ((title === `Next`) && (link != undefined)){
url = link;
}
});
if (temp_url !== url) {
recursive(url);
//`:keep going:`;
}else{
console.log('Close SQLite database.');
db.close();
//`:stop:`;
}
} catch(error) {
throw error;
}
}
recursive(url);
|
Cependant, même dans le cas de 2
..., il semble qu'il puisse être écrit dans la base de données même si elle n'est pas fermée, il semble donc que la commit
soit possible.
Dans le cas d'un ancien PC qui écrit sur le disque dur, si vous validez un par un ou répétez l'ouverture et la fermeture pour écrire dans le fichier SQLite
, la vitesse sera sacrifiée et ce sera lent, mais vous pouvez créer une table dans mémoire et écrire les données. Si vous écrivez le résultat dans le fichier .db
à la fin, cela peut être bon car vous n'avez qu'à valider à la fin.
Chacun des codes de programme 3
et 4
a été écrit pour fermer la base de données lorsque toutes les données ont été écrites, mais cela ne devrait pas être le cas, mais il a été fermé proprement. Drôle, mais non bloquant. Il y a de la place pour la poursuite, mais c'est difficile car le résultat n'entraîne pas d'erreur.
Il n'y a rien de spécial à expliquer.
Ruby sqlite3
| require 'nokogiri'
require 'open-uri'
require 'sqlite3'
url = 'https://13dl.me/list/popular/'
counter = 0
threads = []
SQL =<<EOS
create table manga(
id INTEGER PRIMARY KEY,
title text
);
EOS
db = SQLite3::Database.open("13dlme.db")
db.execute(SQL)
def recursive(counter,url,threads,db)
html = URI.open(url).read
doc = Nokogiri::HTML.parse(html)
html = nil
doc.css('a').each do |x|
xx = x.attr('title')
pa = /^Page/.match?("#{xx}")
p = /^Prev/.match?("#{xx}")
if xx && xx !='' && xx !='Home' && xx !='Popular Manga' then
unless pa | p then
n = /^Next/.match?("#{xx}")
link = ''
if n then
link = x.attr('href')
threads << Thread.new do
recursive(counter,link,threads,db)
end
else
counter += 1
puts "#{counter} #{xx}"
db.execute("insert into manga(id,title) values('#{counter}','#{xx}') ;")
end
end
end
end
doc = nil
end
recursive(counter,url,threads,db)
threads.each(&:join)
db.close
|
for ( while ) loop
https://rentry.co/8o583
Go
Gorutine, SQLit3
https://rentry.co/b79ht
En tant que programme, si l'application Termux
ou Userland
fonctionne sur un smartphone, etc., Node.js
peut être installé comme un package même s'il n'est pas enraciné, donc il fonctionne.
perl5
Rf.https://github.com/radiator-software/p5-net-ssleay/pull/391
Dans le cas de Termux, vous pouvez écrire le programme ci-dessus en installant Node.js
et Axios
, Cheerio
, SQLite3
avec le gestionnaire de package npm
, mais Userland
commence par sélectionner le système d'exploitation, mais selon le système d'exploitation, il peut être approprié. Il existe des différences avec apk
, mais si vous pouvez installer Node.js
, le reste est presque le même que Termux
.
Pour iOS
, j'ai une application d'émulation Terminal appelé iSH
, mais je ne l'ai pas testée sur iOS. Je n'ai pas de Mac et j'ai un vieil iPhone iOS, mais j'ai une aversion physiologique pour une entreprise appelée Apple, donc je ne peux pas le toucher facilement.
Dans Ruby
et Python
, il existe différentes différences en fonction du système d'exploitation avant d'installer la bibliothèque, mais dans le cas de Node.js
, il peut être un avantage qu'une telle différence ne se produise pas. Que JavaScript
soit bon ou non, il doit être réécrit pour qu'il fonctionne uniquement dans le navigateur.
En tant que responsable du droit d'auteur, s'il y a un titre dans la liste que vous gérez, supprimez la procédure.
Lorsqu'il s'agissait d'une manga bank
, les données d'image sur le processus CloudFlare
n'étaient pas autorisées à être accessibles à partir de l'extérieur du Japon par adresse IP
, mais cette fois, il semble qu'il ne l'est pas, et le titre est également en japonais en alphabet. Il peut être conscient de la demande à l'étranger car il correspond au titre de mot.