BinaryWorks.it Official Forum
BinaryWorks.it Official Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 eXtreme Movie Manager 8, 9, 10 Forum
 Scripts
 IMDb API & Web Scraping
 New Topic  Reply to Topic
 Printer Friendly
Previous Page | Next Page
Author Previous Topic Topic Next Topic
Page: of 4 Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

tarzibou
Starting Member

27 Posts

Posted - 11 Aug 2023 :  19:44:05  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Das Grundmuster ist:

foreach (var item in list) {
  ...
}

Das entspricht dieser for-Schleife:

for (i = 0; i < list.Count; i++) {
  var item = list[ i ]; // ohne Leerzeichen in den Klammern, aber wg. Forencode kursiv sonst hier nicht darstellbar
  ...
}

Also ähnlich deinem Delphi-Code, foreach ist halt nur lesbarer und schneller geschrieben, loopt aber im Grunde genau wie bei einer for-Schleife jeden Eintrag in einem IEnumerable (also einer Liste, Array usw.) durch und man hat direkt den Eintrag ohne ihn nochmals per Index aus der Liste zuweisen zu müssen.


Konkret zu den alternateTitles:

foreach (AlternateTitle alternateTitle in alternateTitles) {
  ...
}

- AlternateTitle: das deklariert den Typ des einzelnen Eintrags, hier ist jeder Eintrag vom Typ der Klasse AlternateTitle (du kannst auch "var" schreiben, weil der Compiler den Typ des Einzeleintrags aus der Liste bestimmen kann)
- alternateTitle: das deklariert den Name der Variable des einzelnen Eintrag (den du dann innerhalb der Schleife verwendest)
- alternateTitles: der Variablenname der Liste (der außerhalb vor dem Aufruf der Schleife natürlich bereits bekannt sein muss)


Wenn es für dich einfacher ist, kannst du also auch schreiben:

foreach (var eintrag in alternateTitles) {
  ...
  MessageBox.Show(eintrag.Title); // Ausgabe der Eigenschaft "Title" des Eintrags in einem Popup
  ...
}


quote:
Originally posted by JDommi
Und wie müsste diese Passage korrekt sein, um nicht nur die Anzahl zu bekommen, sondern direkt den CompanyName.

            sbExport.AppendLine("---Production Companies");
            foreach (Company company in companies.Production)
            {
                sbExport.AppendLine($"{companies.Production.Count}");
            }




Sieh dir das zugehörige Bild an (oder mal selbst im Debugger):
https://github.com/tardezyx/tar.IMDbScraper/blob/main/Images/AllCompanies.png

Die Listen innerhalb von allCompanies sind alle identisch aufgebaut, weil sie alle vom selben Typ sind. D.h. die Struktur innerhalb von Production ist dieselbe wie innerhalb der aufgeklappten SpecialEffects.

Beim aufgeklappten Eintrag siehst du dessen Eigenschaften. Was du möchtest, ist die Eigenschaft "Name".

Also kannst du bspw. das schreiben:

foreach (var eintrag in companies.Production) {
  sbExport.AppendLine(eintrag.Name);
}



Und noch was: Falls dich das mit dem sbExport und dem $-Zeichen verwirrt, nimm einfach einen String und bau den selbst zusammen. Das kostet mehr Speicher usw., aber ist für dich zum Verständnis wahrscheinlich leichter. Also


string exportText    = "";     // ein leerer String, den wir nach und nach füllen
string zeilenumbruch = "\r\n"; // ein Carriage-Return und Line Feed (also kurz: ein Zeilenumbruch)

// Vor einem speziellen Sonderzeichen bzw. einem Befehls-Charakter muss ein Escape-Charakter vorangestellt werden
// Der Escape-Charakter in C# ist ein umgekehrter Schrägstrich, daher \r für Carriage-Return

foreach (var eintrag in companies.Production) {
  exportText += eintrag.Name + zeilenumbruch; // beachte das += (damit fügen wir dem vorhandenen Text etwas hinzu)
}

...

string backslash = "\\"; // der umgekehrte Schrägstrich (mit vorangestelltem Escape-Schrägstrich, daher doppelt)
string path      = tbxFolder.Text + backslash + imdbID + ".txt";

File.WriteAllText(path, exportText);

Ich hoffe, es wird langsam klarer. Statt "\r\n" kannst du übrigens auch Environment.NewLine nehmen ;)

Edited by - tarzibou on 11 Aug 2023 20:27:12
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 11 Aug 2023 :  21:49:58  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Jau, jetzt wird's echt langsam klarer
An diese Kurzschreibweise muss man sich echt erst mal gewöhnen, aber die Zeile: (AlternateTitle alternateTitle in alternateTitles)... das war mir doch zu hoch. Vor allem, weil es bei Delphi unerheblich ist, ob man Groß- oder Kleinbuchstaben verwendet. Deine Übersetzung hat bei mir das Lämpchen aber jetzt doch endlich aufgehen lassen
Manche der anderen Schreibweisen sind mir ja auch von Javascript einigermaßen bekannt. Das NewLine wäre in Delphi z.B. #13#10.
Die ganzen Abkürzungen in der Schreibweise sind zwar sehr schön, aber nicht für jemanden, der mit der Sprache noch nie was am Hut hatte. Wahrscheinlich würdest du bei meinen Delphi-Sources auch erstmal so gucken, wie ich mit C# Auf das "foreach" bin ich allerdings echt neidisch!
Morgen Vormittag werde ich mal gucken, ob ich das jetzt nach deiner super Erklärung endlich gebacken kriege!!!

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 12 Aug 2023 :  07:10:28  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by JDommi
Die ganzen Abkürzungen in der Schreibweise sind zwar sehr schön, aber nicht für jemanden, der mit der Sprache noch nie was am Hut hatte. Wahrscheinlich würdest du bei meinen Delphi-Sources auch erstmal so gucken, wie ich mit C# Auf das "foreach" bin ich allerdings echt neidisch!


Du könntest das mit einer Extension-Methode und LINQ sogar noch weiter abkürzen:


companies.Production.Do(x => sbExport.AppendLine(x.Name));


Aber das zu erklären, würde zu weit führen
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 12 Aug 2023 :  09:05:34  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Das stimmt allerdings
Was evtl. noch der Erklärung bedarf:
List<FilmingLocation> filmingLocations = await Scraper.ScrapeAllFilmingLocationsAsync(imdbID);
            LocationsPage? locationsPage = await Scraper.ScrapeLocationsPageAsync(imdbID);

LocationPage - Ich hätte vermutet, dass hiermit eine bestimmte Seite geladen wird. Aber dann hätte die ja eigentlich vor dem List stehen müssen.

Und noch eine letzte Frage, IMDB fragt ja die CountryLocale des users ab und zeigt auf der Seite dann z.B. den Plot auf deutsch an. Kannst du das mit dem Scraper auch nachbilden? Evtl. per zusätzlicher Option?

Last but not least: Bei den Distributoren fehlt noch Land, Jahr und Medium. Dann könnte man z.B. nur die deutschen Vertriebe rausfiltern.
Außerdem wären dann auch keine doppelten Einträge vorhanden.

Und:
Warum ist der letzte Eintrag trotzdem doppelt (Film: Matrix - 1999)?
sbExport.AppendLine("---Production Distributors");
            HashSet<string> uniqueCompanyNames = new HashSet<string>();
            foreach (Company company in companies.Distribution)
            {
                if (!uniqueCompanyNames.Contains(company.Name))
                {
                    uniqueCompanyNames.Add(company.Name);
                    sbExport.AppendLine($"{company.Name}");
                }
            }


Edit:
Hier habe ich Schwierigkeiten:
sbExport.AppendLine($"---Connections FollowedBy");
            foreach (Connection connection in connections.FollowedBy)
            {
                sbExport.AppendLine($"{connection.AssociatedTitle.URL}|{connection.AssociatedTitle.LocalizedTitle} ({connection.AssociatedTitle.YearFrom})");
            }

Wie iteriere ich durch alle Kategorien, die nicht leer sind?

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 12 Aug 2023 :  20:04:54  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Viele "letzte" Fragen.

quote:
Originally posted by JDommi
LocationPage - Ich hätte vermutet, dass hiermit eine bestimmte Seite geladen wird. Aber dann hätte die ja eigentlich vor dem List stehen müssen.

Was meinst du? Die LocationsPage enthält 3 Listen (FilmingDates, FilmingLocations und ProductionDates), aber je Liste maximal 5 Einträge wg. des "mehr"-Button-Problems (würde die Browser-Simulation benötigen, würde zu mehr Abfragen führen, alles Mist).

Daher sollte man ScrapeAllFilmingDatesAsync und ScrapeAllFilmingLocationsAsync verwenden, falls man wirklich alle FilmingDates und alle FilmingLocations braucht. Hier wird jeweils eine JSON-Abfrage genutzt, die wesentlich flinker als HTML-Abfragen sind.

Für ProductionDates habe ich keine JSON-Abfrage einbauen können, weil ich keinen Titel mit mehr als 5 Einträgen gefunden habe. Falls du einen findest, kann ich das noch einbauen. Bis dahin musst du für ProductionDates tatsächlich ScrapeLocationsPageAsync nutzen.

quote:
Originally posted by JDommi
Und noch eine letzte Frage, IMDB fragt ja die CountryLocale des users ab und zeigt auf der Seite dann z.B. den Plot auf deutsch an. Kannst du das mit dem Scraper auch nachbilden? Evtl. per zusätzlicher Option?

Das ist bereits drin - wird aber leider nur in der MainPage (also ScrapeMainPageAsync) bei Outline übersetzt. Alles andere liefert nur englische Texte (selbst bei der Handlungs-Seite, bspw. hier: https://www.imdb.com/title/tt0133093/plotsummary/

quote:
Originally posted by JDommi
Last but not least: Bei den Distributoren fehlt noch Land, Jahr und Medium. Dann könnte man z.B. nur die deutschen Vertriebe rausfiltern.
Außerdem wären dann auch keine doppelten Einträge vorhanden.

Auch das ist schon drin. Du debuggst offenbar nicht richtig. Checke mal diese Eigenschaften: Countries, Notes, YearFrom und YearTo. Wegen unterschiedlicher Jahre gibt es auch mehrfache Einträge zur selben Firma. Das ist auch so auf der IMDb-Seite. Beim Medium weiß ich grad nich aus der Kalten, ob ich die zusammengeführt habe. Glaub schon.

Debuggen: https://www.youtube.com/watch?v=u-HdLtqEOog

quote:
Originally posted by JDommi
Warum ist der letzte Eintrag trotzdem doppelt (Film: Matrix - 1999)?

Wie gesagt: wegen der Jahre.

quote:
Originally posted by JDommi
Hier habe ich Schwierigkeiten:
sbExport.AppendLine($"---Connections FollowedBy");
            foreach (Connection connection in connections.FollowedBy)
            {
                sbExport.AppendLine($"{connection.AssociatedTitle.URL}|{connection.AssociatedTitle.LocalizedTitle} ({connection.AssociatedTitle.YearFrom})");
            }

Wie iteriere ich durch alle Kategorien, die nicht leer sind?


Es gibt bei den Connections keine leeren Kategorien. Das ist dort im Grunde sogar doppelt drin, weil ich die Kategorie einmal als Eigenschaft und einmal als eigenständige Listen habe.

Du musst bei den "FollowedBy" und "Follows" auch beachten, dass er da von dem momentanen Titel ausgeht. D.h. eine vollständige Sammlung erhälst du nur durch FollowedBy beim allerersten Titel oder durch Follows beim allerletzten Titel.

Ich würde es so umsetzen, um eine vollständige Sammlung zu erhalten:
- lese Follows:
--- wenn es leer ist, ist es der allererste Titel
--- wenn es gefüllt ist, ist der erste Eintrag der allererste Titel
- lies FollowedBy des allerersten Titel

Edited by - tarzibou on 12 Aug 2023 20:11:16
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 12 Aug 2023 :  21:22:50  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Habe mich nicht ganz klar ausgedrückt
List<AlternateTitle> alternateTitles = await Scraper.ScrapeAllAlternateTitles(imdbID);
            Companies? companies = await Scraper.ScrapeAllCompaniesAsync(imdbID);        // 5 steps
            Connections? connections = await Scraper.ScrapeAllConnectionsAsync(imdbID);      // 12 steps
            List<Dates> filmingDates = await Scraper.ScrapeAllFilmingDatesAsync(imdbID);
            List<FilmingLocation> filmingLocations = await Scraper.ScrapeAllFilmingLocationsAsync(imdbID);
            LocationsPage? locationsPage = await Scraper.ScrapeLocationsPageAsync(imdbID);
            List<ReleaseDate> releaseDates = await Scraper.ScrapeAllReleaseDatesAsync(imdbID);

Hier hat mich nur gewundert, warum zuerst die Liste mit den filmingLocatgions kommt und danach noch mal LocationsPage.


CountryLocale Hatte das noch nicht getestet


sbExport.AppendLine("---Production Distributors");
            companies.Distribution = companies.Distribution.OrderBy(x => x.Countries).ToList();
            foreach (Company company in companies.Distribution)
            {
                if (company.Countries.Contains("DE"))
                {
                    sbExport.AppendLine($"{company.Countries} {company.Name} {company.YearFrom}}");
                }
            }



Und am Ende:
sbExport.AppendLine($"---Connections FollowedBy");
            foreach (Connection connection in connections.FollowedBy)
            {
                sbExport.AppendLine($"{connection.AssociatedTitle.URL}|{connection.AssociatedTitle.LocalizedTitle} ({connection.AssociatedTitle.YearFrom})");
            }

Wie baue ich am Besten eine äußere foreach-Schleife ein?
In der Art wie "foreach connections.categories {...}"
Um nicht für jede Kategorie den gleichen Code schreiben zu müssen.


Das ist mein bisheriger Code:
// --- daten aufbereiten --------------------------------------------------------------------
            StringBuilder sbExport = new StringBuilder();

            sbExport.AppendLine("---Alternate Titles");
            alternateTitles = alternateTitles.OrderBy(x => x.Country?.ID).ToList();
            foreach (AlternateTitle alternateTitle in alternateTitles)
            {
                sbExport.AppendLine($"{alternateTitle.Country?.ID}: {alternateTitle.Title}");
            }

            // ...
            sbExport.AppendLine("---Release Dates");
            releaseDates = releaseDates.OrderBy(x => x.Country?.ID).ToList();
            foreach (ReleaseDate releaseDate in releaseDates)
            {
                if (releaseDate.Date != null)
                {
                    sbExport.AppendLine($"{releaseDate.Country?.ID}: {releaseDate.Date.Value.ToString("dd.MM.yyyy")}");
                }
            }


            // ...
            sbExport.AppendLine("---Filming Locations");
            foreach (FilmingLocation filmingLocation in filmingLocations)
            {
                sbExport.AppendLine($"{filmingLocation.Address}");
            }


            // ...
            sbExport.AppendLine("---Production Companies");
            foreach (Company company in companies.Production)
            {
                sbExport.AppendLine($"{company.Name}");
            }


            // ... Die IF-Routine funktioniert nicht !!!
            sbExport.AppendLine("---Production Distributors");
            foreach (Company company in companies.Distribution)
            {
                if (company.Countries[0] == "Germany")
                {
                    sbExport.AppendLine($"{company.Countries[0]} - {company.Name} ({company.YearFrom})");
                }
            }


            // ...
            sbExport.AppendLine($"---Connections FollowedBy");
            foreach (Connection connection in connections.FollowedBy)
            {
                sbExport.AppendLine($"{connection.AssociatedTitle.URL}|{connection.AssociatedTitle.LocalizedTitle} ({connection.AssociatedTitle.YearFrom})");
            }


            // ...

            // --- Daten exportieren --------------------------------------------------------------------
            string path = $"{tbxFolder.Text}\\{imdbID}.txt";
            File.WriteAllText(path, sbExport.ToString());
        }

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 13 Aug 2023 :  15:41:23  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by JDommi
Hier hat mich nur gewundert, warum zuerst die Liste mit den filmingLocatgions kommt und danach noch mal LocationsPage.

Die Reihenfolge spielt keine Rolle. Das sind zwei separate Abfragen mit unterschiedlichen Resultaten.

quote:
Originally posted by JDommi
Wie baue ich am Besten eine äußere foreach-Schleife ein?
In der Art wie "foreach connections.categories {...}"
Um nicht für jede Kategorie den gleichen Code schreiben zu müssen.

In diesem Fall wäre es am Einfachsten, einfach alle Ergebnisse aller Listen in eine große Liste zu hängen - dann kannst du einfach via Kategorie filtern.

      List<Company> companies = new();
      companies.AddRange(await Scraper.ScrapeCompaniesAsync(imdbID, CompanyCategory.Distribution));
      companies.AddRange(await Scraper.ScrapeCompaniesAsync(imdbID, CompanyCategory.Miscellaneous));
      companies.AddRange(await Scraper.ScrapeCompaniesAsync(imdbID, CompanyCategory.Production));
      companies.AddRange(await Scraper.ScrapeCompaniesAsync(imdbID, CompanyCategory.Sales));
      companies.AddRange(await Scraper.ScrapeCompaniesAsync(imdbID, CompanyCategory.SpecialEffects));

Oder, falls du schon allCompanies gezogen hast:

      List<Company> companies = new();
      companies.AddRange(allCompanies.Distribution);
      companies.AddRange(allCompanies.Miscellaneous);
      companies.AddRange(allCompanies.Production);
      companies.AddRange(allCompanies.Sales);
      companies.AddRange(allCompanies.SpecialEffects);

Filtern ginge so:

      foreach (var company in companies) { 
        switch (company.Category) {
          case "Distribution":
            // mache was mit den Distribution-Firmen
            break;
          case "Sales":
            // mache was anderes mit Sales-Firmen
            break;
        }
      }

oder so:

      foreach (var company in companies.Where(x => x.Category == "Distribution")) { 
        // mache was mit den Distribution-Firmen
      }


Wenn du wirklich nur Firmen haben willst, wo Deutschland als Land hinterlegt ist, solltest du die Liste vorn vorherein filtern:

      foreach (var company in companies.Where(x => x.Countries.Contains("Germany"))) {

      }

Ergibt aber nur Sinn bei Distribution-Firmen, weil IMDb für die anderen Firmen keine Länderangaben mitgibt.

Edited by - tarzibou on 13 Aug 2023 15:45:51
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 13 Aug 2023 :  16:30:19  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Genau so hatte ich mir das gedacht

Bei mehreren Kategorien dann wahrscheinlich so:
foreach (var company in companies) { 
        switch (company.Category) {
          case "Distribution":
            // mache was mit den Distribution-Firmen
            break;
          case "Sales", "Production", "SpecialEffects":
            // mache was anderes mit Sales-Firmen
            break;
        }
      }


Wenn alle erforderlichen Daten eingelesen sind, bzw. meine Coderergänzungen okay sind, wollte ich OnCreation Event 2 Parameter mitgeben: den IMDBLink und das gewünschte Land für manche Infos wie halt die Distribution Companies oder den Native Title. Mit Fallback ins Englische. Das wird bestimmt schneller gehen, als den Resultattext mit MagicScript zu zerpflücken.

Morgen werde ich noch (versuchen) zusätzliche Infos abzurufen. Die, die du mir freundlicherweise schon eingebaut hattest, habe ich jetzt komplett fertig. Da fehlt evtl. nur noch ein xxx.Notes, das mit abgespeichert werden muss.

Die zwei separaten Abfragen mit unterschiedlichen Resultaten: Hier hatte ich am Anfang gedacht, die beiden Zeilen würden zusammen gehören.

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 14 Aug 2023 :  12:44:56  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hierbei habe ich gerade leichte Probleme:
sbExport.AppendLine($"---Awards");
            foreach (Award award in awards)
            {
                if (award.Category != null)
                {
                    if (award.Persons.Count > 0)
                    {
                        sbExport.AppendLine($"{award.Event}|{award.IsWinner} [{award.Name} {award.Year}] -->{award.Category} >{award.Persons[0]?.Name}");
                    }
                    else
                    {
                        sbExport.AppendLine($"{award.Event}|{award.IsWinner} [{award.Name} {award.Year}] -->{award.Category}");
                    }
                }
            }

Gibt es eine Kurzform für {award.Persons[0 to award.Persons.Count-1]?.Name}? Ansonsten müsste ich die Namen erst über award.Persons().ToList bearbeiten oder besser noch per foreach damit ich da ein Komma zwischen bekomme.

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 14 Aug 2023 :  14:52:41  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Bei dem, was du alles exportieren willst, wäre es vielleicht sinnvoll, dich mit (XML- oder JSON-) (De-)Serialisierung und zugehörigem Dateiexport zu befassen, so dass der automatisch die Knoten entsprechend der Quelldaten füllt. Denn so wie es mir aussieht, bastelst du hier eine Zwischendatei, die du dann wohl irgendwie mit XMM nochmal durchforsten möchtest, oder?

Nutze Linq für's filtern und dann string.Join() für's zusammenfassen. Bspw. mal alle Länder für allAllternateTitles:


List<AlternateTitle>  allAlternateTitles  = await Scraper.ScrapeAllAlternateTitles(imdbID);

IEnumerable<string?> titlesCountries = allAlternateTitles
  .Where(x => x.Country != null)
  .Select(x => x?.Country?.Name);

string titlesCountriesAsString = string.Join(
  ", ",
  titlesCountries
);
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 14 Aug 2023 :  16:19:59  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Denn so wie es mir aussieht, bastelst du hier eine Zwischendatei, die du dann wohl irgendwie mit XMM nochmal durchforsten möchtest, oder?

Genau, allerdings wirklich nur die Felder, die ich mit XMM nicht komplett auslesen kann.
Die Standard-Infos würde ich evtl. mal testen, die kommen aber nicht ins Script rein.

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 15 Aug 2023 :  15:56:28  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
https://www.mediafire.com/file/aqeoa59d9non8oc/tar.IMDbExporter.zip/file

Beim StartParameter muss ich noch den tt-String isolieren.
Aber was hältst du bisher davon? Du würdest da natürlich noch jede Menge optimieren können

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 16 Aug 2023 :  00:09:13  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hab mich bissl ausgetobt:
https://github.com/tardezyx/tar.IMDbScraper/releases/download/1.1.0/tar.IMDbExporter.zip
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 16 Aug 2023 :  10:50:44  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by tarzibou

Hab mich bissl ausgetobt:
https://github.com/tardezyx/tar.IMDbScraper/releases/download/1.1.0/tar.IMDbExporter.zip



WOW!
Wesentlich strukturierter und schneller als mein Versuch

Was ich gerade noch implementiert habe:
tbxID.Text = arguments.Length > 0
              ? ParseIMDBLink(arguments[0])
              : "tt0133093"; // Matrix (1999)
und nach region --- fields ---
#region --- parse imdb link -------------------------------------------------------------------
        static string ParseIMDBLink(string url)
        {
            // Remove any trailing slashes from the URL
            url = url.TrimEnd('/');

            // Find the last occurrence of '/'
            int lastSlashIndex = url.LastIndexOf('/');

            if (lastSlashIndex >= 0)
            {
                // Extract the portion of the URL after the last '/'
                string identifierPart = url.Substring(lastSlashIndex + 1);

                // Remove any non-numeric characters from the extracted part
                string numericPart = new string(identifierPart.Where(char.IsDigit).ToArray());

                // Add "tt" in front of the numeric part
                string imdbIdentifier = "tt" + numericPart;

                return imdbIdentifier;
            }
            else
            {
                return null; // URL format is not recognized
            }
        }

        #endregion



Und gut zu wissen, dass sogar einem "Profi" wie dir noch ein Fehler unterlaufen kann: Es werden nämlich keinerlei Connections mehr gespeichert.
iMDbTitle.Connections ist immer null... Keine Ahnung, warum.

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 16 Aug 2023 :  14:58:10  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Um die IMDb-ID aus einer URL zu fischen, wäre RegEx sinnvoller und wesentlich kürzer:


      string url = @"https://www.imdb.com/title/tt0069697/?ref_=nv_sr_srsg_0_tt_4_nm_4_q_zwei%2520wie%2520pech";
      Match match = Regex.Match(url, @"tt\d+", RegexOptions.IgnoreCase);

      string imdbID = match.Success
        ? match.Value
        : string.Empty;


Ich musste gerade den Scraper updaten, weil IMDb bei einigen Sachen die Hashes geändert hat. Die FAQ Page braucht eine komplette Überarbeitung, sonst sieht es gut aus. Mir fiel noch auf, dass die Zahlenkonvertierung beim Rating etwas schief hing, sollte jetzt auch richtig funktionieren. Zuguterletzt fehlte noch eine Kategorie bei den Connections: "Features". Habe ich ergänzt.

Alles aktualisiert und auch das Fischen der ID aus dem Parameter eingebaut, findest du hier:
https://github.com/tardezyx/tar.IMDbScraper/releases/tag/1.1.1
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 16 Aug 2023 :  17:29:36  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Was soll ich sagen? :3 Daumen hoch:

Die RegEx müsste leider noch mal überarbeitet werden, ich im Laufe der Zeit unterschiedliche Schreibweisen des IMDB-Links bekommen habe.
- https://www.imdb.com/title/tt0069697/?ref_=nv_sr_srsg_0_tt_4_nm_4_q_zwei%2520wie%2520pech
- http://www.imdb.com/Title?0062622
- http://akas.imdb.com/title/tt
und sogar noch http://www.imdb.de/tt

In #CUSTOM8# habe ich sogar noch mehr Varianten durch den trailing Slash teilweise mit/ohne ?ref.

Ich würde den RegEx so schreiben, da die Ziffernfolge ja immer 7-stellig ist. Oder würde d+ reichen?
Match match = Regex.Match(arguments[0], @"tt\d{7}", RegexOptions.IgnoreCase);

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 17 Aug 2023 :  03:05:08  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Kannst du ja anpassen, wie du es brauchst. Zum Testen hier lang: https://regex101.com

Die IMDb-ID wird dynamisch erhöht. Es gibt mittlerweile Titel mit 8 Stellen, bspw. https://www.imdb.com/title/tt11315808/
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 17 Aug 2023 :  10:09:02  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Ups, mit 8 auch schon? Hab ich noch gar nicht bemerkt
Dann muss da tatsächlich \d{7,} hin...
Danke für den Hinweis!
Heute werde ich mal gucken, welche Daten alle mit diesem Anzeige-Button versehen sind und dann, welche Daten davon wirklich gebraucht werden.
Das Script werde ich anschließend, wie bei OFDB, als IMDB_plus-Script anlegen, da ja nur XMM 10 in der Lage ist, einen Text zu laden. Die anderen müssen sich dann halt mit den standardmäßig angezeigten begnnügen.

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

JDommi
Administrator

Germany
4637 Posts

Posted - 17 Aug 2023 :  17:37:31  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Trivia ist erfolgreich eingebaut.
Aber die letzte Routine: Ich bekomme die Goofs nicht hin
Irgendwie erkennt der die Kategorien nicht, obwohl das fast identisch ist mit den Connections.
https://www.mediafire.com/file/h3ib96sqh5ajrxr/tar.IMDbExporter_%25283%2529.zip/file
Was übersehe ich da?

In order to achieve what is possible, you have to try the impossible over and over again.
Hermann Hesse
Go to Top of Page

tarzibou
Starting Member

27 Posts

Posted - 18 Aug 2023 :  17:43:32  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Es gibt keine in der Kategorie Anachronism.
Go to Top of Page
Page: of 4 Previous Topic Topic Next Topic   Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
Previous Page | Next Page
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
BinaryWorks.it Official Forum © Binaryworks.it Go To Top Of Page
Generated in 0.26 sec. Powered By: Snitz Forums 2000 Version 3.4.07