VB .Net navigate each link and get a specific url - vb.net

I'm having trouble using the web browser in VB .NET to navigate a list of URL's inside a multiline textbox, wait for them for load and get a specific URL (should contain a specific word).
What I have until now:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim webClient As New System.Net.WebClient
'Dim htmlDoc As New HtmlAgilityPack.HtmlDocument()
For Each strLine As String In TextBox4.Text.Split(vbCrLf)
Console.WriteLine("Turning False")
Console.WriteLine("----")
WebBrowser1.Navigate(strLine)
Console.WriteLine("Waiting for navigation - " & strLine)
Console.WriteLine("Navigated")
Next
For Each link In links
TextBox6.Text = TextBox6.Text & link & vbCrLf
Next
Dim lines As New List(Of String)(TextBox6.Lines)
For i As Integer = lines.Count - 1 To 1 Step -1
If lines(i) = lines(i - 1) Then
lines.RemoveAt(i)
End If
Next
TextBox6.Lines = lines.ToArray
End Sub
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
For Each ele As HtmlElement In WebBrowser1.Document.Links
'Get whatever text there is in the 'href' attribute
Dim eletarget As String = ele.GetAttribute("href")
'Add it to the listbox
If eletarget.Contains("cfsecure") Then
links.Add(eletarget)
'Carry on to the next link
End If
Next
End Sub
First of all, it seems it doesn't wait until fully loaded. After that, I don't get any link from what I asked (don't know if it's related to the first problem I have or any mistake in my code getting the href with the word "cfsecure").
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
For Each ele As HtmlElement In WebBrowser1.Document.Links
'Get whatever text there is in the 'href' attribute
Dim eletarget As String = ele.GetAttribute("href")
'Add it to the listbox
If eletarget.Contains("cfsecure") Then
links.Add(eletarget)
'Carry on to the next link
End If
Next
End Sub
What I'm missing here?

Related

Loop through each item in Listbox and load a webpage

I'm trying to load a new webpage through the control webview2 in .net6+ windows forms, and I'm using a listbox to extract any single item and add it to the url to load on webview.
For example in listbox I have:
11
22
33
44
55
I would like at the press of a button that a loop starts to load one by one,each of these items like
WebView21.Source = New Uri("https://google.it" & ListBox1.Items.first & "rest of the url")
and after the webpage is loaded, it s supposed to extract it's html to check if a certain string is present with
Dim html As String
html = Await WebView21.ExecuteScriptAsync("document.documentElement.outerHTML;")
If html.Contains("Not found") Then
MsgBox("In Vacanza")
Else
MsgBox("Attivo")
End If
End Sub
after that, it goes back to the second listbox item, load the webview, check the html and so on.
My question is how can I loop the WebView in order to pick each of the items one by one and to proceed to do these little things in the while?
p.s. Once the loop arrives to the last listbox item, would it be possible to start it again from the first item?
Much thanks
edit1:
I'm trying with
Private ReadOnly resetEvent As New ManualResetEvent(False)
Async Sub scanWeb()
For Each listBoxElem As String In ListBox1.Items
resetEvent.Reset()
AddHandler WebView2.CoreWebView2.NavigationCompleted, AddressOf OnNavigationCompleted
WebView2.Source = New Uri("https://ikalogs.ru/tools/map/?page=1&server=22&world=10&state=active&search=city&allies%5B1%5D=&allies%5B2%5D=&allies%5B3%5D=&allies%5B4%5D=&nick=" & listBoxElem & "&ally=&island=&city=&x=&y=")
Await Task.Run(Sub() resetEvent.WaitOne())
RemoveHandler WebView2.CoreWebView2.NavigationCompleted, AddressOf OnNavigationCompleted
Dim html As String
html = Await WebView2.ExecuteScriptAsync("document.documentElement.outerHTML;")
If html.Contains("Not found") Then
DataGridView1.Rows.Add(listBoxElem, "IN vacanza")
Else
DataGridView1.Rows.Add(listBoxElem, "Attivo")
End If
Next
End Sub
Private Sub OnNavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
resetEvent.Set()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebView2 = New WebView2()
WebView2.EnsureCoreWebView2Async()
End Sub
but it seems the loop doesn't wait for the process to end and it goes straight to the next listbox item...
best way is to enumerate listBox items in a for-each loop : (I added an escape way -simple mouse clic on form - to quit loop)
Dim wStop As Boolean
sub scanWeb()
Do
For Each listBoxElem As String In ListBox1.Items
WebView21.Source = New Uri("https://google.it" & listBoxElem & "rest of the url")
'etc....
Next
Loop Until wStop = True
wStop = False
end sub
'way to stop scan
Private Sub form_clic(sender As Object, e As MouseEventArgs) Handles MyBase.MouseClick
wStop = True
End Sub
*** Update *****
The webview2 control is rather made to display data, and I have no experience on it.
Also I suggest you use a simpler method, based on System.Net.WebClient() and associated with threading.
Here is a start of code that works:
Dim wStop As Boolean
Dim i As Integer = 0
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim BackProcess = New Thread(Sub() Me.scanWeb())
BackProcess.Priority = ThreadPriority.Normal
BackProcess.Start()
end sub
Sub scanWeb()
Do While Not wStop
Dim WC As New System.Net.WebClient()
'change url for your need
Dim url As String = "https://www.google.fr/search?q=" & ListBox1.Items(i)
Dim s As System.IO.Stream = WC.OpenRead(url)
Dim sr As New System.IO.StreamReader(s)
Dim html As String = sr.ReadToEnd()
If html.Contains("Not found") Then 'beginInvoke allows the back task to communicate with UI
Me.BeginInvoke(Sub() DataGridView1.Rows.Add(ListBox1.Items(i), "In vacanza"))
Else
Me.BeginInvoke(Sub() DataGridView1.Rows.Add(ListBox1.Items(i), "Attivo"))
End If
i += 1
If i > ListBox1.Items.Count - 1 Then i = 0
Loop
End Sub
'button event to stop scanning
Private Sub stopScan_Click(sender As Object, e As EventArgs) Handles stopScan.Click
wStop = True
End Sub

Remove line from text file which listed in list box

I have a text file(its hosts file)
I can add lines(domains) to the file through a text box.
When i click the 'Save' button, inputted value(domain) saves to the text(hosts) file with a 127.0.0.1 prefix. At the same time it shows that in a list box too(while showing it in list box, it won't show the prefix(127.0.0.1). It'll only show the value got from the text field)
What i need now is that,
When i click and select an item from the list box and press 'Remove' button, it needs to be removed from both the list box and the text(hosts) file.
Also, while removing the selected item from the list box, the prefix(127.0.0.1) also should be removed from the file without leaving an empty line.
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles BtnCustomDomainremove.Click
ListBox1.Items.Remove(ListBox1.SelectedItem)
Dim delLine As Integer = 1
Dim lines As List(Of String) = System.IO.File.ReadAllLines("C:\Windows\System32\drivers\etc\hosts").ToList
lines.RemoveAt(delLine - 1)
System.IO.File.WriteAllLines("C:\Windows\System32\drivers\etc\hosts", lines)
MessageBox.Show("URL removed from Block List !", "Custom Block List")
End Sub
Above code it removes the top value from file and selected one from list box.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lines As List(Of String) = System.IO.File.ReadAllLines("C:\Windows\System32\drivers\etc\hosts").ToList
Dim Findstring = IO.File.ReadAllText("C:\Windows\System32\drivers\etc\hosts")
Dim Lookfor As String = CStr("127.0.0.1" + ListBox1.SelectedItem)
If lines.Contains(Lookfor) Then
For i = 0 To Findstring.Length - 1
lines.Remove(Lookfor)
Next
System.IO.File.WriteAllLines("C:\Windows\System32\drivers\etc\hosts", lines)
ListBox1.Items.Remove(ListBox1.SelectedItem)
MessageBox.Show("URL removed from Block List !", "Custom Block List")
Else
MsgBox("string not found")
End If
End Sub
This code works for me, you might have to tweak it slightly to match your prefereneces however, it seems to find each occurunce (if there's more than one) of the selected item in listbox1 (if there's only one occurance you can remove the for loop.
Instead of Reading and Writing the file on every change to the list, save the list when the form closes. Read the file when the form opens and populate the list. While the form is open just add and remove list items as you normally would.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim path = "C:\Windows\System32\drivers\etc\hosts.txt"
Dim lines() As String = File.ReadAllLines(path)
'Substring(9) the characters in "127.0.0.1" are index 0-8 so we begin with index 9
'and return the rest of the string.
Dim TrimmedList = From line In lines
Select line.Substring(9)
For Each item In TrimmedList
ListBox2.Items.Add(item)
Next
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
Dim sb As New StringBuilder()
For Each item In ListBox2.Items
sb.AppendLine("127.0.0.1" & item.ToString)
Next
Dim path = "C:\Windows\System32\drivers\etc\hosts.txt"
File.WriteAllText(path, sb.ToString)
End Sub
Requires
Imports System.IO
Imports System.Text
try this code
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles BtnCustomDomainremove.Click
ListBox1.Items.Remove(ListBox1.SelectedItem)
Dim details As String = ""
For Each o As Object In ListBox1.Items
details += o.ToString + vbNewLine
Next
My.Computer.FileSystem.WriteAllText("C:\Windows\System32\drivers\etc\hosts", details, False)
MessageBox.Show("URL removed from Block List !", "Custom Block List")
End Sub

if the file not exits then return no error vb

I have start this application every things its work fine but i have a small bug but i can not find the solution to solve the error.
i have debug it and the error its because the file not exist
is there any way to me to populate my datagridview with all *.gif images From a directory and the check if its null or some thing like that.
What i mean is is there any way to my to populate all gif images found on the chose Directory?
in fact i have all ready try like this but i get one error "Provided column already belongs to the DataGridView control.
Well finaly i have found a solution to load all images from a directory to a datagridview programmatic
Here Is The Working Code
Public Class Form5
Private Sub addBtn_Click(sender As Object, e As EventArgs) Handles addBtn.Click
'Populate()
ShowImages()
End Sub
'CLEAR DATAGRIDVIEW
Private Sub clearBtn_Click(sender As Object, e As EventArgs) Handles clearBtn.Click
DataGridView1.Rows.Clear()
End Sub
'WHEN AN IMAGE IS CLICKED
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
MessageBox.Show("You Clicked Image At Col: " + e.ColumnIndex.ToString() + " Row: " + e.RowIndex.ToString())
End Sub
Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Public Sub ShowImages()
Dim directory As New System.IO.DirectoryInfo("C:\avitogifconverter\")
If directory.Exists Then
Dim pngFiles() As System.IO.FileInfo = directory.GetFiles("*.gif")
For Each pngFile As System.IO.FileInfo In pngFiles
If pngFile.Exists Then
Dim image = System.Drawing.Image.FromFile(pngFile.FullName)
Using image
Dim count = 1
' do something with the image like show in picture box
'CONSTRUCT IMG COLUMN
Dim imgCol As DataGridViewImageColumn = New DataGridViewImageColumn()
imgCol.HeaderText = "Photo"
imgCol.Name = "Col 1"
DataGridView1.Columns.Add(imgCol)
'CONSTRUCT ROWS
'FIRST ROW
Dim img As Image = System.Drawing.Image.FromFile(pngFile.FullName)
Dim row As Object() = New Object() {img, img, img}
DataGridView1.Rows.Add(row)
End Using
End If
Next
End If
End Sub
End Class
Using Directory.EnumerateFiles, you could do something like this:
Dim row = New List(Of Image)(3)
For Each filename In Directory.EnumerateFiles("C:\avitogifconverter", "*.gif")
row.Add(Image.FromFile(filename))
If row.Count = 3 Then
DataGridView1.Rows.Add(row.ToArray())
row.Clear()
End If
Next
If row.Count > 0 Then
DataGridView1.Rows.Add(row.ToArray())
row.Clear()
End If

VB.NET How to get text from an HTML table?

I'm trying to access certain tables and values from a certain html page inside of a webbrowser control. Here's what i'm trying to access:
https://gyazo.com/c4312f860397d0f86ccce425d1fb3d48
In the end, I'm trying to access the value="100" inside of the input name="Server[players]". Is there any way to do this? I'm not using any external addons for visual studio or anything. I've already gotten this working:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim divs = WebBrowser1.Document.GetElementsByTagName("div")
For Each div As HtmlElement In divs
If div.GetAttribute("id") = ("statusdetail-ajax") Then
Dim status As String = div.InnerText
Label1.Text = status
End If
Next
Which just shows me the online/offline status. Any help is greatly appreciated!
You want the GetAttribute() method, like so:
Private Sub DisplayMetaDescription()
If (WebBrowser1.Document IsNot Nothing) Then
Dim Elems As HtmlElementCollection
Dim WebOC as WebBrowser = WebBrowser1
Elems = WebOC.Document.GetElementsByTagName("META")
For Each elem As HtmlElement In Elems
Dim NameStr As String = elem.GetAttribute("name")
If ((NameStr IsNot Nothing) And (NameStr.Length <> 0)) Then
If NameStr.ToLower().Equals("description") Then
Dim ContentStr As String = elem.GetAttribute("content")
MessageBox.Show("Document: " & WebOC.Url.ToString() & vbCrLf & "Description: " & ContentStr)
End If
End If
Next
End If
End Sub
Taken from:
https://msdn.microsoft.com/en-us/library/system.windows.forms.htmlelement.getattribute(v=vs.110).aspx
EDIT:
Here's the same concept adapted to your code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim inputs = WebBrowser1.Document.GetElementsByTagName("input")
For Each input As HtmlElement In inputs
If input.GetAttribute("id") = ("Server_players") Then
Dim status As String = input.GetAttribute("value")
Label1.Text = status
End If
Next
End Sub
In other words, InnerText returns everything between elements, while GetAttribute() returns an attribute inside an element.
<element attribute="Value">Inner Text</element>

Read .txt file and display into different button

I'm trying to display some text on my button but I can only display those text on 1 button. My buttons are separated like Button1.Text, Button2.Text, and Button3.Text and my .txt file can only be displayed in Button1.Text. Here is the code that I did so far.
Private Sub FormMenu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim R As New IO.StreamReader("TestFile.txt")
Button1.Text = R.ReadToEnd()
R.Close()
End Sub
Inside my .txt file got something like
First Button
Second Button
Third Button
and I want my system be able to read them and display into each of the button. How to do that? Thank you.
Use something like...
Private Sub FormMenu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim lines() As String = System.IO.File.ReadAllLines("TestFile.txt")
For i As Integer = 1 To lines.Length
Dim ctl As Control = Me.Controls.Find("Button" & i, True).FirstOrDefault
If Not IsNothing(ctl) Then
ctl.Text = lines(i - 1)
End If
Next
End Sub
Private Sub FormMenu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim R As New IO.StreamReader("TestFile.txt")
Dim words As String() = R.ReadToEnd().Split(New String() {Environment.NewLine})
Button1.Text = words(0)
Button2.Text = words(1)
Button3.Text = words(2)
R.Close()
End Sub