diff --git a/Grosshandel2/Grosshandel2.sln b/Grosshandel2/Grosshandel2.sln
new file mode 100644
index 0000000..4ecc49f
--- /dev/null
+++ b/Grosshandel2/Grosshandel2.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.11.35222.181
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grosshandel2", "Grosshandel2\Grosshandel2.csproj", "{5D9FD5F3-4DDE-4E45-9959-04AA4F5C3518}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5D9FD5F3-4DDE-4E45-9959-04AA4F5C3518}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5D9FD5F3-4DDE-4E45-9959-04AA4F5C3518}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D9FD5F3-4DDE-4E45-9959-04AA4F5C3518}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5D9FD5F3-4DDE-4E45-9959-04AA4F5C3518}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E7F8D8D2-C3A7-4A56-A1E4-C87D3096EEC0}
+ EndGlobalSection
+EndGlobal
diff --git a/Grosshandel2/Grosshandel2/Artikel.cs b/Grosshandel2/Grosshandel2/Artikel.cs
new file mode 100644
index 0000000..c5d972a
--- /dev/null
+++ b/Grosshandel2/Grosshandel2/Artikel.cs
@@ -0,0 +1,11 @@
+namespace Grosshandel2
+{
+ public class Artikel
+ {
+ public int ArtikelId { get; set; }
+ public string Name { get; set; }
+ public decimal Preis { get; set; }
+ public decimal Grosshandelspreis { get; set; }
+ public byte[] Bild { get; set; }
+ }
+}
diff --git a/Grosshandel2/Grosshandel2/DatabaseManager.cs b/Grosshandel2/Grosshandel2/DatabaseManager.cs
new file mode 100644
index 0000000..ec654b0
--- /dev/null
+++ b/Grosshandel2/Grosshandel2/DatabaseManager.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Data;
+using MySql.Data.MySqlClient;
+
+namespace Grosshandel2
+{
+ public class DatabaseManager
+ {
+ private string _connectionString = "Server=192.168.178.201;Database=grosshandel;User ID=root;Password=1td5rugut8;";
+
+ public DataTable GetArtikelListe()
+ {
+ using (var connection = new MySqlConnection(_connectionString))
+ {
+ var query = @"SELECT a.ArtikelId, a.Name, p.Preis, p.Grosshandelspreis
+ FROM Artikel a
+ JOIN Preise p ON a.ArtikelId = p.ArtikelId";
+
+ using (var adapter = new MySqlDataAdapter(query, connection))
+ {
+ var dataTable = new DataTable();
+ adapter.Fill(dataTable);
+ return dataTable;
+ }
+ }
+ }
+
+ public void AddArtikel(Artikel artikel, byte[] bild)
+ {
+ using (var connection = new MySqlConnection(_connectionString))
+ {
+ connection.Open();
+
+ using (var transaction = connection.BeginTransaction())
+ {
+ // Füge den Artikel hinzu
+ var insertArtikelQuery = "INSERT INTO Artikel (Name, Bild) VALUES (@Name, @Bild); SELECT LAST_INSERT_ID();";
+ var command = new MySqlCommand(insertArtikelQuery, connection, transaction);
+ command.Parameters.AddWithValue("@Name", artikel.Name);
+ command.Parameters.AddWithValue("@Bild", bild ?? (object)DBNull.Value);
+
+ // Hole die zuletzt eingefügte ArtikelId
+ var artikelId = Convert.ToInt32(command.ExecuteScalar());
+
+ // Füge den Preis hinzu
+ var insertPreisQuery = "INSERT INTO Preise (ArtikelId, Preis, Grosshandelspreis) VALUES (@ArtikelId, @Preis, @Grosshandelspreis);";
+ command = new MySqlCommand(insertPreisQuery, connection, transaction);
+ command.Parameters.AddWithValue("@ArtikelId", artikelId);
+ command.Parameters.AddWithValue("@Preis", artikel.Preis);
+ command.Parameters.AddWithValue("@Grosshandelspreis", artikel.Grosshandelspreis);
+ command.ExecuteNonQuery();
+
+ transaction.Commit();
+ }
+ }
+ }
+
+
+ public void UpdateArtikel(Artikel artikel, byte[] bild)
+ {
+ using (var connection = new MySqlConnection(_connectionString))
+ {
+ connection.Open();
+
+ using (var transaction = connection.BeginTransaction())
+ {
+ var updateArtikelQuery = "UPDATE Artikel SET Name = @Name, Bild = @Bild WHERE ArtikelId = @ArtikelId;";
+ var command = new MySqlCommand(updateArtikelQuery, connection, transaction);
+ command.Parameters.AddWithValue("@Name", artikel.Name);
+ command.Parameters.AddWithValue("@Bild", bild ?? (object)DBNull.Value);
+ command.Parameters.AddWithValue("@ArtikelId", artikel.ArtikelId);
+ command.ExecuteNonQuery();
+
+ var updatePreisQuery = "UPDATE Preise SET Preis = @Preis, Grosshandelspreis = @Grosshandelspreis WHERE ArtikelId = @ArtikelId;";
+ command = new MySqlCommand(updatePreisQuery, connection, transaction);
+ command.Parameters.AddWithValue("@Preis", artikel.Preis);
+ command.Parameters.AddWithValue("@Grosshandelspreis", artikel.Grosshandelspreis);
+ command.Parameters.AddWithValue("@ArtikelId", artikel.ArtikelId);
+ command.ExecuteNonQuery();
+
+ transaction.Commit();
+ }
+ }
+ }
+
+ public void DeleteArtikel(int artikelId)
+ {
+ using (var connection = new MySqlConnection(_connectionString))
+ {
+ connection.Open();
+
+ using (var transaction = connection.BeginTransaction())
+ {
+ var deletePreisQuery = "DELETE FROM Preise WHERE ArtikelId = @ArtikelId;";
+ var command = new MySqlCommand(deletePreisQuery, connection, transaction);
+ command.Parameters.AddWithValue("@ArtikelId", artikelId);
+ command.ExecuteNonQuery();
+
+ var deleteArtikelQuery = "DELETE FROM Artikel WHERE ArtikelId = @ArtikelId;";
+ command = new MySqlCommand(deleteArtikelQuery, connection, transaction);
+ command.Parameters.AddWithValue("@ArtikelId", artikelId);
+ command.ExecuteNonQuery();
+
+ transaction.Commit();
+ }
+ }
+ }
+ public byte[] GetBildByArtikelId(int artikelId)
+ {
+ byte[] bild = null;
+
+ using (var connection = new MySqlConnection(_connectionString))
+ {
+ connection.Open();
+ var query = "SELECT Bild FROM Artikel WHERE ArtikelId = @ArtikelId";
+ using (var command = new MySqlCommand(query, connection))
+ {
+ command.Parameters.AddWithValue("@ArtikelId", artikelId);
+ using (var reader = command.ExecuteReader())
+ {
+ if (reader.Read())
+ {
+ bild = reader["Bild"] as byte[];
+ }
+ }
+ }
+ }
+
+ return bild;
+ }
+ }
+}
diff --git a/Grosshandel2/Grosshandel2/FrmMain.Designer.cs b/Grosshandel2/Grosshandel2/FrmMain.Designer.cs
new file mode 100644
index 0000000..f6ca829
--- /dev/null
+++ b/Grosshandel2/Grosshandel2/FrmMain.Designer.cs
@@ -0,0 +1,158 @@
+namespace Grosshandel2
+{
+ partial class FrmMain
+ {
+ private System.ComponentModel.IContainer components = null;
+ private System.Windows.Forms.DataGridView dataGridView1;
+ private System.Windows.Forms.TextBox txtName;
+ private System.Windows.Forms.NumericUpDown numericPreis;
+ private System.Windows.Forms.NumericUpDown numericGrosshandelspreis;
+ private System.Windows.Forms.Button btnAdd;
+ private System.Windows.Forms.Button btnUpdate;
+ private System.Windows.Forms.Button btnDelete;
+ private System.Windows.Forms.PictureBox pictureBox;
+ private System.Windows.Forms.TextBox txtBildPfad;
+ private System.Windows.Forms.Button btnBrowseImage;
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ private void InitializeComponent()
+ {
+ this.dataGridView1 = new System.Windows.Forms.DataGridView();
+ this.txtName = new System.Windows.Forms.TextBox();
+ this.numericPreis = new System.Windows.Forms.NumericUpDown();
+ this.numericGrosshandelspreis = new System.Windows.Forms.NumericUpDown();
+ this.btnAdd = new System.Windows.Forms.Button();
+ this.btnUpdate = new System.Windows.Forms.Button();
+ this.btnDelete = new System.Windows.Forms.Button();
+ this.pictureBox = new System.Windows.Forms.PictureBox();
+ this.txtBildPfad = new System.Windows.Forms.TextBox();
+ this.btnBrowseImage = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericPreis)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericGrosshandelspreis)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+ this.SuspendLayout();
+ //
+ // dataGridView1
+ //
+ this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.dataGridView1.Location = new System.Drawing.Point(12, 12);
+ this.dataGridView1.Name = "dataGridView1";
+ this.dataGridView1.RowHeadersWidth = 51;
+ this.dataGridView1.RowTemplate.Height = 24;
+ this.dataGridView1.Size = new System.Drawing.Size(776, 150);
+ this.dataGridView1.TabIndex = 0;
+ this.dataGridView1.SelectionChanged += new System.EventHandler(this.dataGridView1_SelectionChanged);
+ //
+ // txtName
+ //
+ this.txtName.Location = new System.Drawing.Point(12, 200);
+ this.txtName.Name = "txtName";
+ this.txtName.Size = new System.Drawing.Size(200, 22);
+ this.txtName.TabIndex = 1;
+ //
+ // numericPreis
+ //
+ this.numericPreis.DecimalPlaces = 2;
+ this.numericPreis.Location = new System.Drawing.Point(12, 250);
+ this.numericPreis.Name = "numericPreis";
+ this.numericPreis.Size = new System.Drawing.Size(120, 22);
+ this.numericPreis.TabIndex = 2;
+ //
+ // numericGrosshandelspreis
+ //
+ this.numericGrosshandelspreis.DecimalPlaces = 2;
+ this.numericGrosshandelspreis.Location = new System.Drawing.Point(12, 300);
+ this.numericGrosshandelspreis.Name = "numericGrosshandelspreis";
+ this.numericGrosshandelspreis.Size = new System.Drawing.Size(120, 22);
+ this.numericGrosshandelspreis.TabIndex = 3;
+ //
+ // btnAdd
+ //
+ this.btnAdd.Location = new System.Drawing.Point(250, 200);
+ this.btnAdd.Name = "btnAdd";
+ this.btnAdd.Size = new System.Drawing.Size(75, 23);
+ this.btnAdd.TabIndex = 4;
+ this.btnAdd.Text = "Hinzufügen";
+ this.btnAdd.UseVisualStyleBackColor = true;
+ this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
+ //
+ // btnUpdate
+ //
+ this.btnUpdate.Location = new System.Drawing.Point(250, 250);
+ this.btnUpdate.Name = "btnUpdate";
+ this.btnUpdate.Size = new System.Drawing.Size(75, 23);
+ this.btnUpdate.TabIndex = 5;
+ this.btnUpdate.Text = "Aktualisieren";
+ this.btnUpdate.UseVisualStyleBackColor = true;
+ this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
+ //
+ // btnDelete
+ //
+ this.btnDelete.Location = new System.Drawing.Point(250, 300);
+ this.btnDelete.Name = "btnDelete";
+ this.btnDelete.Size = new System.Drawing.Size(75, 23);
+ this.btnDelete.TabIndex = 6;
+ this.btnDelete.Text = "Löschen";
+ this.btnDelete.UseVisualStyleBackColor = true;
+ this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
+ //
+ // pictureBox
+ //
+ this.pictureBox.Location = new System.Drawing.Point(400, 200);
+ this.pictureBox.Name = "pictureBox";
+ this.pictureBox.Size = new System.Drawing.Size(200, 200);
+ this.pictureBox.TabIndex = 7;
+ this.pictureBox.TabStop = false;
+ this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+ //
+ // txtBildPfad
+ //
+ this.txtBildPfad.Location = new System.Drawing.Point(400, 150);
+ this.txtBildPfad.Name = "txtBildPfad";
+ this.txtBildPfad.Size = new System.Drawing.Size(200, 22);
+ this.txtBildPfad.TabIndex = 8;
+ //
+ // btnBrowseImage
+ //
+ this.btnBrowseImage.Location = new System.Drawing.Point(625, 150);
+ this.btnBrowseImage.Name = "btnBrowseImage";
+ this.btnBrowseImage.Size = new System.Drawing.Size(75, 23);
+ this.btnBrowseImage.TabIndex = 9;
+ this.btnBrowseImage.Text = "Durchsuchen";
+ this.btnBrowseImage.UseVisualStyleBackColor = true;
+ this.btnBrowseImage.Click += new System.EventHandler(this.btnBrowseImage_Click);
+ //
+ // FrmMain
+ //
+ this.ClientSize = new System.Drawing.Size(800, 450);
+ this.Controls.Add(this.btnBrowseImage);
+ this.Controls.Add(this.txtBildPfad);
+ this.Controls.Add(this.pictureBox);
+ this.Controls.Add(this.btnDelete);
+ this.Controls.Add(this.btnUpdate);
+ this.Controls.Add(this.btnAdd);
+ this.Controls.Add(this.numericGrosshandelspreis);
+ this.Controls.Add(this.numericPreis);
+ this.Controls.Add(this.txtName);
+ this.Controls.Add(this.dataGridView1);
+ this.Name = "FrmMain";
+ this.Text = "Artikelverwaltung";
+ this.Load += new System.EventHandler(this.FrmMain_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericPreis)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numericGrosshandelspreis)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+ }
+ }
+}
diff --git a/Grosshandel2/Grosshandel2/FrmMain.cs b/Grosshandel2/Grosshandel2/FrmMain.cs
new file mode 100644
index 0000000..4c396d1
--- /dev/null
+++ b/Grosshandel2/Grosshandel2/FrmMain.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Data;
+using System.Windows.Forms;
+
+namespace Grosshandel2
+{
+ public partial class FrmMain : Form
+ {
+ private DatabaseManager _dbManager;
+ private Artikel _currentArtikel;
+
+ public FrmMain()
+ {
+ InitializeComponent();
+ _dbManager = new DatabaseManager();
+ }
+
+ private void FrmMain_Load(object sender, EventArgs e)
+ {
+ LoadArtikelData();
+ }
+
+ private void LoadArtikelData()
+ {
+ try
+ {
+ var artikelTable = _dbManager.GetArtikelListe();
+ if (artikelTable != null)
+ {
+ dataGridView1.DataSource = artikelTable;
+ }
+ else
+ {
+ MessageBox.Show("Keine Artikel gefunden.");
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Fehler beim Laden der Artikel: {ex.Message}");
+ }
+ }
+
+ private void btnAdd_Click(object sender, EventArgs e)
+ {
+ // Erstelle ein neues Artikel-Objekt
+ var artikel = new Artikel
+ {
+ Name = txtName.Text,
+ Preis = numericPreis.Value,
+ Grosshandelspreis = numericGrosshandelspreis.Value
+ };
+
+ // Lade das Bild, falls ein Bildpfad angegeben ist
+ byte[] bildBytes = null;
+ if (!string.IsNullOrEmpty(txtBildPfad.Text))
+ {
+ bildBytes = LoadImageFromFile(txtBildPfad.Text);
+ }
+
+ try
+ {
+ // Füge den Artikel zur Datenbank hinzu
+ _dbManager.AddArtikel(artikel, bildBytes);
+
+ // Lade die Artikel-Daten neu
+ LoadArtikelData();
+
+ // Bestätigungsnachricht
+ MessageBox.Show("Artikel erfolgreich hinzugefügt.");
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Fehler beim Hinzufügen des Artikels: " + ex.Message);
+ }
+ }
+
+ private void btnUpdate_Click(object sender, EventArgs e)
+ {
+ if (_currentArtikel != null)
+ {
+ _currentArtikel.Name = txtName.Text;
+ _currentArtikel.Preis = numericPreis.Value;
+ _currentArtikel.Grosshandelspreis = numericGrosshandelspreis.Value;
+ _currentArtikel.Bild = File.ReadAllBytes(txtBildPfad.Text);
+ _dbManager.UpdateArtikel(_currentArtikel, _currentArtikel.Bild);
+ LoadArtikelData();
+ }
+ }
+
+ private void btnDelete_Click(object sender, EventArgs e)
+ {
+ if (_currentArtikel != null)
+ {
+ _dbManager.DeleteArtikel(_currentArtikel.ArtikelId);
+ LoadArtikelData();
+ _currentArtikel = null;
+ ClearForm();
+ }
+ }
+
+ private void dataGridView1_SelectionChanged(object sender, EventArgs e)
+ {
+ if (dataGridView1.SelectedRows.Count > 0)
+ {
+ var selectedRow = dataGridView1.SelectedRows[0];
+ var artikelId = Convert.ToInt32(selectedRow.Cells["ArtikelId"].Value);
+
+ // Abrufen des Bildes aus der Datenbank
+ var bildBytes = _dbManager.GetBildByArtikelId(artikelId);
+
+ if (bildBytes != null && bildBytes.Length > 0)
+ {
+ using (var ms = new MemoryStream(bildBytes))
+ {
+ pictureBox.Image = Image.FromStream(ms);
+ }
+ }
+ else
+ {
+ pictureBox.Image = null;
+ }
+
+ txtName.Text = selectedRow.Cells["Name"].Value.ToString();
+ numericPreis.Value = Convert.ToDecimal(selectedRow.Cells["Preis"].Value);
+ numericGrosshandelspreis.Value = Convert.ToDecimal(selectedRow.Cells["Grosshandelspreis"].Value);
+ txtBildPfad.Text = string.Empty; // Optional, falls du den Bildpfad anzeigen möchtest
+ }
+ }
+
+ private void ClearForm()
+ {
+ txtName.Clear();
+ numericPreis.Value = 0;
+ numericGrosshandelspreis.Value = 0;
+ txtBildPfad.Clear();
+ pictureBox.Image = null;
+ }
+ private void btnBrowseImage_Click(object sender, EventArgs e)
+ {
+ using (var openFileDialog = new OpenFileDialog())
+ {
+ if (openFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ txtBildPfad.Text = openFileDialog.FileName;
+ pictureBox.Image = Image.FromFile(openFileDialog.FileName);
+ }
+ }
+ }
+ private byte[] LoadImageFromFile(string filePath)
+ {
+ if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
+ {
+ return null;
+ }
+
+ return File.ReadAllBytes(filePath);
+ }
+
+
+ }
+}
diff --git a/Grosshandel2/Grosshandel2/FrmMain.resx b/Grosshandel2/Grosshandel2/FrmMain.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/Grosshandel2/Grosshandel2/FrmMain.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Grosshandel2/Grosshandel2/Grosshandel2.csproj b/Grosshandel2/Grosshandel2/Grosshandel2.csproj
new file mode 100644
index 0000000..bd1d994
--- /dev/null
+++ b/Grosshandel2/Grosshandel2/Grosshandel2.csproj
@@ -0,0 +1,15 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ true
+ enable
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Grosshandel2/Grosshandel2/Program.cs b/Grosshandel2/Grosshandel2/Program.cs
new file mode 100644
index 0000000..0a7fa23
--- /dev/null
+++ b/Grosshandel2/Grosshandel2/Program.cs
@@ -0,0 +1,17 @@
+namespace Grosshandel2
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ // To customize application configuration such as set high DPI settings or default font,
+ // see https://aka.ms/applicationconfiguration.
+ ApplicationConfiguration.Initialize();
+ Application.Run(new FrmMain());
+ }
+ }
+}
\ No newline at end of file
diff --git a/webCrawlerGoogle/.gitattributes b/webCrawlerGoogle/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/webCrawlerGoogle/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/webCrawlerGoogle/.gitignore b/webCrawlerGoogle/.gitignore
new file mode 100644
index 0000000..9491a2f
--- /dev/null
+++ b/webCrawlerGoogle/.gitignore
@@ -0,0 +1,363 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Oo]ut/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
\ No newline at end of file
diff --git a/webCrawlerGoogle/webCrawlerGoogle.sln b/webCrawlerGoogle/webCrawlerGoogle.sln
new file mode 100644
index 0000000..c1cbc0e
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35122.118
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "webCrawlerGoogle", "webCrawlerGoogle\webCrawlerGoogle.csproj", "{36E507D2-6D2C-43DD-9E30-F7E151018942}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {36E507D2-6D2C-43DD-9E30-F7E151018942}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {36E507D2-6D2C-43DD-9E30-F7E151018942}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {36E507D2-6D2C-43DD-9E30-F7E151018942}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {36E507D2-6D2C-43DD-9E30-F7E151018942}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FB32F52A-3116-4EB2-A3D9-B6435A5B7A2E}
+ EndGlobalSection
+EndGlobal
diff --git a/webCrawlerGoogle/webCrawlerGoogle/Form1.Designer.cs b/webCrawlerGoogle/webCrawlerGoogle/Form1.Designer.cs
new file mode 100644
index 0000000..11f1309
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle/Form1.Designer.cs
@@ -0,0 +1,110 @@
+namespace webCrawlerGoogle
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ txtCategory = new TextBox();
+ txtCity = new TextBox();
+ btnSearch = new Button();
+ lstResults = new ListBox();
+ lblFortschritt = new Label();
+ SuspendLayout();
+ //
+ // txtCategory
+ //
+ txtCategory.Location = new Point(14, 14);
+ txtCategory.Margin = new Padding(4, 3, 4, 3);
+ txtCategory.Name = "txtCategory";
+ txtCategory.PlaceholderText = "Rubrik (z.B. Restaurant)";
+ txtCategory.Size = new Size(303, 23);
+ txtCategory.TabIndex = 0;
+ //
+ // txtCity
+ //
+ txtCity.Location = new Point(14, 44);
+ txtCity.Margin = new Padding(4, 3, 4, 3);
+ txtCity.Name = "txtCity";
+ txtCity.PlaceholderText = "Stadt (z.B. Berlin)";
+ txtCity.Size = new Size(303, 23);
+ txtCity.TabIndex = 1;
+ //
+ // btnSearch
+ //
+ btnSearch.Location = new Point(14, 74);
+ btnSearch.Margin = new Padding(4, 3, 4, 3);
+ btnSearch.Name = "btnSearch";
+ btnSearch.Size = new Size(303, 27);
+ btnSearch.TabIndex = 2;
+ btnSearch.Text = "Suchen";
+ btnSearch.UseVisualStyleBackColor = true;
+ btnSearch.Click += btnSearch_Click;
+ //
+ // lstResults
+ //
+ lstResults.FormattingEnabled = true;
+ lstResults.ItemHeight = 15;
+ lstResults.Location = new Point(14, 107);
+ lstResults.Margin = new Padding(4, 3, 4, 3);
+ lstResults.Name = "lstResults";
+ lstResults.Size = new Size(303, 169);
+ lstResults.TabIndex = 3;
+ //
+ // lblFortschritt
+ //
+ lblFortschritt.AutoSize = true;
+ lblFortschritt.Location = new Point(18, 290);
+ lblFortschritt.Name = "lblFortschritt";
+ lblFortschritt.Size = new Size(10, 15);
+ lblFortschritt.TabIndex = 4;
+ lblFortschritt.Text = ".";
+ //
+ // Form1
+ //
+ AutoScaleDimensions = new SizeF(7F, 15F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(334, 350);
+ Controls.Add(lblFortschritt);
+ Controls.Add(lstResults);
+ Controls.Add(btnSearch);
+ Controls.Add(txtCity);
+ Controls.Add(txtCategory);
+ Margin = new Padding(4, 3, 4, 3);
+ Name = "Form1";
+ Text = "Google Business Suche";
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+ private System.Windows.Forms.TextBox txtCategory;
+ private System.Windows.Forms.TextBox txtCity;
+ private System.Windows.Forms.Button btnSearch;
+ private System.Windows.Forms.ListBox lstResults;
+ private Label lblFortschritt;
+ }
+}
diff --git a/webCrawlerGoogle/webCrawlerGoogle/Form1.cs b/webCrawlerGoogle/webCrawlerGoogle/Form1.cs
new file mode 100644
index 0000000..1209ea5
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle/Form1.cs
@@ -0,0 +1,267 @@
+using MySql.Data.MySqlClient;
+using HtmlAgilityPack;
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Diagnostics;
+using OpenQA.Selenium;
+using OpenQA.Selenium.Chrome;
+
+namespace webCrawlerGoogle
+{
+ public partial class Form1 : Form
+ {
+ private static string connectionString = "Server=192.168.178.201;Database=domainchecker;User ID=root;Password=1td5rugut8;";
+ private static int searchCounter = 0;
+ private static int maxSearchesBeforeVPNChange = 20; // Anzahl der Suchanfragen, bevor der VPN gewechselt wird
+ private static int pauseAfterEachSearchMs = 500; // Pause nach jeder Suchanfrage (2 Sekunden)
+ private static int longPauseAfterBatchMs = 60000; // Längere Pause nach einer Reihe von Suchanfragen (1 Minute)
+ private static int fortschritt = 0;
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private async void btnSearch_Click(object sender, EventArgs e)
+ {
+ var searchParams = LoadSearchParamsFromDatabase();
+
+ foreach (var param in searchParams)
+ {
+ string category = param.Rubrik;
+ string city = param.Stadt;
+
+ //AppendToOutput($"Suche nach: {category} in {city}");
+ await ScrapeGoogleResults(category, city);
+
+ searchCounter++;
+ if (searchCounter >= maxSearchesBeforeVPNChange)
+ {
+ ChangeVPN();
+ searchCounter = 0;
+
+ //AppendToOutput("Längere Pause nach VPN-Wechsel...");
+ await Task.Delay(longPauseAfterBatchMs);
+ }
+ else
+ {
+ //AppendToOutput("Kurze Pause nach Suchanfrage...");
+ await Task.Delay(pauseAfterEachSearchMs);
+ }
+ }
+ }
+
+ private async Task ScrapeGoogleResults(string category, string city)
+ {
+ string query = $"{category}+in+{city}";
+ string searchUrl = $"https://www.google.com/search?q=" + query;
+ //$"https://www.google.com/search?q={Uri.EscapeDataString(query)}";
+
+ var options = new ChromeOptions();
+ options.AddArgument("headless");
+ options.AddArgument("disable-gpu");
+
+ using (var driver = new ChromeDriver(options))
+ {
+ driver.Navigate().GoToUrl(searchUrl);
+
+ await Task.Delay(2000); // Warte ein wenig, damit die Seite vollständig geladen wird
+
+ var titleNodes = driver.FindElements(By.XPath("//h3[@class='LC20lb MBeuO DKV0Md']"));
+
+ if (titleNodes != null && titleNodes.Count > 0)
+ {
+
+ foreach (var node in titleNodes)
+ {
+ // Hier könntest du auch die zugehörige URL extrahieren
+ var parent = node.FindElement(By.XPath("./ancestor::a"));
+ if (parent != null)
+ {
+ string url = parent.GetAttribute("href");
+ string cleanedUrl = CleanUrl(url);
+
+ if (!CheckIfUrlExistsInDatabase(cleanedUrl))
+ {
+ fortschritt++;
+ SaveUrlToDatabase(cleanedUrl, city, category);
+ AppendToOutput(cleanedUrl);
+ lblFortschritt.Text = $"Aktuell hinzugefügt Anzahl {fortschritt}";
+ Application.DoEvents();
+ }
+ }
+ }
+ }
+ else
+ {
+ AppendToOutput("Keine Titel gefunden.");
+ }
+ }
+ }
+ bool CheckIfUrlExistsInDatabase(string url)
+ {
+ using (MySqlConnection conn = new MySqlConnection(connectionString))
+ {
+ conn.Open();
+ string query = "SELECT COUNT(*) FROM webCrawler WHERE webseite = @url";
+ using (MySqlCommand cmd = new MySqlCommand(query, conn))
+ {
+ cmd.Parameters.AddWithValue("@url", url);
+ int count = Convert.ToInt32(cmd.ExecuteScalar());
+ return count > 0;
+ }
+ }
+ }
+
+ void SaveUrlToDatabase(string url, string city, string category)
+ {
+ using (MySqlConnection conn = new MySqlConnection(connectionString))
+ {
+ conn.Open();
+ string query = "INSERT INTO webCrawler(email, webseite, stadt, rubrik) VALUES(@value1, @value2, @value3, @value4)";
+ using (MySqlCommand cmd = new MySqlCommand(query, conn))
+ {
+ cmd.Parameters.AddWithValue("@value1", ""); // Leere E-Mail, da nicht angegeben
+ cmd.Parameters.AddWithValue("@value2", url);
+ cmd.Parameters.AddWithValue("@value3", city);
+ cmd.Parameters.AddWithValue("@value4", category);
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+
+ static string CleanUrl(string url)
+ {
+ // Uri-Objekt erstellen, um die URL zu parsen
+ Uri uri = new Uri(url);
+
+ // Entfernen von "www."
+ string host = uri.Host.Replace("www.", "");
+
+ // Zusammensetzen der bereinigten URL
+ string cleanedUrl = $"{host}";
+
+ return cleanedUrl;
+ }
+
+ private async void ChangeVPN()
+ {
+ AppendToOutput("Wechsel des VPN-Servers...");
+
+ // VPN trennen
+ ExecuteCommand("net stop nordvpn-service");
+ await Task.Delay(30000); // Warte, um sicherzustellen, dass der Dienst vollständig gestoppt wird
+
+ // VPN wieder verbinden
+ ExecuteCommand("net start nordvpn-service");
+ await Task.Delay(30000); // Warte, um sicherzustellen, dass der Dienst vollständig gestartet wird
+
+ AppendToOutput("VPN-Server gewechselt.");
+ }
+
+ private void ExecuteCommand(string command)
+ {
+ var processInfo = new ProcessStartInfo("cmd.exe", "/c " + command)
+ {
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true
+ };
+
+ using (var process = Process.Start(processInfo))
+ {
+ string output = process.StandardOutput.ReadToEnd();
+ string error = process.StandardError.ReadToEnd();
+ process.WaitForExit();
+
+ if (!string.IsNullOrEmpty(output))
+ {
+ AppendToOutput("Output: " + output);
+ }
+
+ if (!string.IsNullOrEmpty(error))
+ {
+ AppendToOutput("Fehler: " + error);
+ }
+
+ if (process.ExitCode != 0)
+ {
+ AppendToOutput("Der Befehl '" + command + "' wurde nicht erfolgreich ausgeführt.");
+ }
+ }
+ }
+
+ private void AppendToOutput(string text)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new Action(() => AppendToOutput(text)));
+ return;
+ }
+
+ lstResults.Items.Add(text + Environment.NewLine);
+ }
+
+ private List LoadSearchParamsFromDatabase()
+ {
+ var searchParams = new List();
+
+ using (MySqlConnection conn = new MySqlConnection(connectionString))
+ {
+ conn.Open();
+
+ // Städte aus der Tabelle Staedte laden
+ var staedte = new List();
+ string queryStaedte = "SELECT staedte FROM staedte";
+ using (MySqlCommand cmdStaedte = new MySqlCommand(queryStaedte, conn))
+ {
+ using (MySqlDataReader readerStaedte = cmdStaedte.ExecuteReader())
+ {
+ while (readerStaedte.Read())
+ {
+ staedte.Add(readerStaedte.GetString("staedte"));
+ }
+ }
+ }
+
+ // Rubriken aus der Tabelle Rubriken laden
+ var rubriken = new List();
+ string queryRubriken = "SELECT rubriken FROM rubriken";
+ using (MySqlCommand cmdRubriken = new MySqlCommand(queryRubriken, conn))
+ {
+ using (MySqlDataReader readerRubriken = cmdRubriken.ExecuteReader())
+ {
+ while (readerRubriken.Read())
+ {
+ rubriken.Add(readerRubriken.GetString("rubriken"));
+ }
+ }
+ }
+
+ // Kombiniere jede Rubrik mit jeder Stadt und füge sie zur Liste hinzu
+ foreach (var stadt in staedte)
+ {
+ foreach (var rubrik in rubriken)
+ {
+ searchParams.Add(new SearchParam
+ {
+ Rubrik = rubrik,
+ Stadt = stadt
+ });
+ }
+ }
+ }
+
+ return searchParams;
+ }
+ }
+
+ public class SearchParam
+ {
+ public string Rubrik { get; set; }
+ public string Stadt { get; set; }
+ }
+}
+
+
diff --git a/webCrawlerGoogle/webCrawlerGoogle/Form1.resx b/webCrawlerGoogle/webCrawlerGoogle/Form1.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle/Form1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/webCrawlerGoogle/webCrawlerGoogle/Program.cs b/webCrawlerGoogle/webCrawlerGoogle/Program.cs
new file mode 100644
index 0000000..0d279ed
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle/Program.cs
@@ -0,0 +1,17 @@
+namespace webCrawlerGoogle
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ // To customize application configuration such as set high DPI settings or default font,
+ // see https://aka.ms/applicationconfiguration.
+ ApplicationConfiguration.Initialize();
+ Application.Run(new Form1());
+ }
+ }
+}
\ No newline at end of file
diff --git a/webCrawlerGoogle/webCrawlerGoogle/Sicherung.txt b/webCrawlerGoogle/webCrawlerGoogle/Sicherung.txt
new file mode 100644
index 0000000..64aa8b0
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle/Sicherung.txt
@@ -0,0 +1,198 @@
+NUGET:
+
+Install-Package Selenium.WebDriver
+Install-Package Selenium.WebDriver.ChromeDriver
+
+
+
+ private const string ApiKey = "GELÖSCHT"; //"AIzaSyCjdysuuyc2bs4ikqT8xyIpPJHiDZ4CEo4"; // Füge hier deinen API-Schlüssel ein
+ private string connectionString = "Server=192.168.178.201;Database=domainchecker;User ID=root;Password=1td5rugut8;";
+
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private async void btnSearch_Click(object sender, EventArgs e)
+ {
+ var searchParams = LoadSearchParamsFromDatabase();
+
+ foreach (var param in searchParams)
+ {
+ string category = param.Rubrik;
+ string city = param.Stadt;
+
+ string requestUri = $"https://maps.googleapis.com/maps/api/place/textsearch/json?query={category}+in+{city}&key={ApiKey}";
+ await FetchResults(requestUri, city, category);
+
+ }
+ Console.Beep();
+ MessageBox.Show("Fertig!");
+ }
+
+
+ private async Task FetchResults(string requestUri, string stadt, string rubrik)
+ {
+ using (HttpClient client = new HttpClient())
+ {
+ bool hasNextPage = true;
+
+ while (hasNextPage)
+ {
+ HttpResponseMessage response = await client.GetAsync(requestUri);
+ if (response.IsSuccessStatusCode)
+ {
+ string jsonResult = await response.Content.ReadAsStringAsync();
+ JObject result = JObject.Parse(jsonResult);
+
+ foreach (var place in result["results"])
+ {
+ string placeId = (string)place["place_id"];
+ string website = await GetPlaceDetails(placeId);
+ if (!string.IsNullOrEmpty(website))
+ {
+ string cleanedUrl = CleanUrl(website);
+ lstResults.Items.Add(cleanedUrl);
+ SaveToDatabase(cleanedUrl, stadt, rubrik);
+ }
+ }
+
+ if (result["next_page_token"] != null)
+ {
+ string nextPageToken = (string)result["next_page_token"];
+ await Task.Delay(2000); // 2 Sekunden warten
+ requestUri = $"https://maps.googleapis.com/maps/api/place/textsearch/json?pagetoken={nextPageToken}&key={ApiKey}";
+ }
+ else
+ {
+ hasNextPage = false;
+ }
+ }
+ else
+ {
+ MessageBox.Show("Fehler bei der Anfrage: " + response.StatusCode);
+ hasNextPage = false;
+ }
+ }
+ }
+ }
+
+
+ private async Task GetPlaceDetails(string placeId)
+ {
+ string requestUri = $"https://maps.googleapis.com/maps/api/place/details/json?place_id={placeId}&fields=website&key={ApiKey}";
+
+ using (HttpClient client = new HttpClient())
+ {
+ HttpResponseMessage response = await client.GetAsync(requestUri);
+ if (response.IsSuccessStatusCode)
+ {
+ string jsonResult = await response.Content.ReadAsStringAsync();
+ JObject result = JObject.Parse(jsonResult);
+
+ return (string)result["result"]["website"];
+ }
+
+ return null;
+ }
+ }
+
+ private void SaveToDatabase(string website, string stadt, string rubrik)
+ {
+ using (MySqlConnection conn = new MySqlConnection(connectionString))
+ {
+ conn.Open();
+ string queryCheck = "SELECT COUNT(*) FROM webCrawler WHERE webseite = @website";
+ using (MySqlCommand cmdCheck = new MySqlCommand(queryCheck, conn))
+ {
+ cmdCheck.Parameters.AddWithValue("@website", website);
+ int count = Convert.ToInt32(cmdCheck.ExecuteScalar());
+
+ if (count == 0)
+ {
+ string queryInsert = "INSERT INTO webCrawler (webseite, stadt, rubrik) VALUES (@website, @stadt, @rubrik)";
+ using (MySqlCommand cmdInsert = new MySqlCommand(queryInsert, conn))
+ {
+ cmdInsert.Parameters.AddWithValue("@website", website);
+ cmdInsert.Parameters.AddWithValue("@stadt", stadt);
+ cmdInsert.Parameters.AddWithValue("@rubrik", rubrik);
+
+ cmdInsert.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+ }
+ public static string CleanUrl(string url)
+ {
+ // Entferne das Protokoll (http, https) und 'www.'
+ Uri uri = new Uri(url);
+ string host = uri.Host;
+
+ // Prüfen, ob "www." am Anfang des Hosts ist und entfernen
+ if (host.StartsWith("www."))
+ {
+ host = host.Substring(4);
+ }
+
+ return host;
+ }
+ private List LoadSearchParamsFromDatabase()
+ {
+ var searchParams = new List();
+
+ using (MySqlConnection conn = new MySqlConnection(connectionString))
+ {
+ conn.Open();
+
+ // Zuerst alle Städte aus der Tabelle Staedte laden
+ var staedte = new List();
+ string queryStaedte = "SELECT staedte FROM staedte";
+ using (MySqlCommand cmdStaedte = new MySqlCommand(queryStaedte, conn))
+ {
+ using (MySqlDataReader readerStaedte = cmdStaedte.ExecuteReader())
+ {
+ while (readerStaedte.Read())
+ {
+ staedte.Add(readerStaedte.GetString("staedte"));
+ }
+ }
+ }
+
+ // Dann alle Rubriken aus der Tabelle Rubriken laden
+ var rubriken = new List();
+ string queryRubriken = "SELECT rubriken FROM rubriken";
+ using (MySqlCommand cmdRubriken = new MySqlCommand(queryRubriken, conn))
+ {
+ using (MySqlDataReader readerRubriken = cmdRubriken.ExecuteReader())
+ {
+ while (readerRubriken.Read())
+ {
+ rubriken.Add(readerRubriken.GetString("rubriken"));
+ }
+ }
+ }
+
+ // Kombiniere jede Rubrik mit jeder Stadt und füge sie zur Liste hinzu
+ foreach (var stadt in staedte)
+ {
+ foreach (var rubrik in rubriken)
+ {
+ searchParams.Add(new SearchParam
+ {
+ Rubrik = rubrik,
+ Stadt = stadt
+ });
+ }
+ }
+ }
+
+ return searchParams;
+ }
+ }
+
+ public class SearchParam
+ {
+ public string Rubrik { get; set; }
+ public string Stadt { get; set; }
+ }
\ No newline at end of file
diff --git a/webCrawlerGoogle/webCrawlerGoogle/app.manifest.xml b/webCrawlerGoogle/webCrawlerGoogle/app.manifest.xml
new file mode 100644
index 0000000..bb32719
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle/app.manifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/webCrawlerGoogle/webCrawlerGoogle/webCrawlerGoogle.csproj b/webCrawlerGoogle/webCrawlerGoogle/webCrawlerGoogle.csproj
new file mode 100644
index 0000000..8bf19ad
--- /dev/null
+++ b/webCrawlerGoogle/webCrawlerGoogle/webCrawlerGoogle.csproj
@@ -0,0 +1,20 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ true
+ enable
+ app.manifest.xml
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file