I am working on a C# Project with Visual Studio 2013.
My Problem:
There is a website on which you can search something and it displays a few results (i.e 30 of 1200). So, at the bottom of this website is a button to show more 30 results.
I succeeded in reading the current 30 results (using the WebClient), but I have no idea how to find a solution to get ALL the results.
I know what to do, but I don't know how to do it. I have to click on the button until there are no hidden results anymore. After that I have to read out the html (with my existing code).
I searched on google for a few hours and found some things with "headless" browsers, and I also tried to use the "InvokeMember"-Method of the Webbrowser, but it doesn't work. I only get the 30 results if I print out the HTML.
I hope you understand my question. Please help me.
Thanks.
WebBrowserControl Scroll to Bottom
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
webBrowser1.Navigated += (s1, e1) =>
{
if (webBrowser1.Document.Body != null) webBrowser1.Document.Body.ScrollIntoView(false);
};
}
Or
if (theDoc.Body.InnerHtml != null)
{
try
{
webBrowser1.Document.Window.ScrollTo(0, webBrowser1.Document.Body.ScrollRectangle.Height);
timer2.Enabled = true;
}
catch { }
}
else
{
timer2.Enabled = true;
}
It looks like you need to implement pagination.
Depending on your requirements, you might need server or client side.
The link might help you decide:
StackOverflow Client Side vs Server Side
Related
I use a proprietary IDE that is part of a large software package. At its core, however, C# is used as the language. Most .Net components and classes can be used. I can use it to create my own functions / WinForms, which are then integrated into an ERP system. This means that you can expand this system yourself. This is quite well implemented but there is no documentation and the support is also poor at this point. That's why I'm trying my luck here. Maybe someone can help.
I am currently programming a WinForms window that contains a WebBrowser control (wb). I'm pretty sure this is IE. I can programmatically create and include HTML code via MemoryStream (ms):
ms.Write(bytes, 0, bytes.Length);
wb.DocumentStream = ms;
It all works very well. Now I want to get events from the browser and have had the IDE create event handlers for this:
try {
wb.Click += new EventHandler(wb_Click);
...} etc.
public void wb_Click (object sender, EventArgs e)
{ }
The compiler shows no errors. During the execution I get the error message: The Click event is invalid for this ActiveX control. What could trigger this error? W. Wolf
Thanks for your tips! I was able to solve this with the following code:
...
HtmlElementCollection elements = wb.Document.GetElementsByTagName("span");
for (int n = 0; n < elements.Count;n++)
{
elements[n].Click += new HtmlElementEventHandler(el_Click);
}
...
public void el_Click (object sender, HtmlElementEventArgs e)
{
HtmlElement el = (HtmlElement) sender;
ShowInfo(el.Id);
}
I can continue to work with it.
How do I embed a youtube video into my C# project?
I've looked at so many others that "answer" this question but, I can't find what I'm looking for.
I've tried many different ways to embed them but, they don't work.
I'm looking to use a web browser to just play the video but, with two options: loop and pause/play.
Reason I'm doing this is because I'm making a twitch chat bot and I'm trying to add song requests.
Latest attempt (because it was there so I decided on trying it out):
bool MUrlSpecify = true;
private void btnMSetCurrent_Click(object sender, EventArgs e)
{
const string page = "<html><head><title></title></head><body>{0}</body></html>";
string YTUrl;
if(MUrlSpecify == true)
{
YTUrl = "https://www.youtube.com/embed/" + txtMSetCurrent.Text;
wbMPlayer.DocumentText = string.Format(page, "");
}
}
(MUrlSpecify is a variable I added because later I'm going to have a search function)
If anyone can tell me how I should do this I'll try their method because I'm all
out of ideas.
Try to use webbrowser.NavigateToString("player code");
Get the code from share button in youtube. Work perfectly.
Example: wb.NavigateToString("<iframe width=\"420\" height=\"315\" src=\"https://www.youtube.com/embed/dSrozYNxAA4\" frameborder=\"0\" allowfullscreen></iframe>");
NOT using API
I am currently attempting to use a web browser in C# to load google maps and automatically focus on my current location, however, for some reason I cannot get this to work properly. The idea is simple. Load Google maps, and either execute the script to focus on my current location:
mapBrowser.Document.InvokeScript("mylocation.onButtonClick");
Or, invoke the button click through an HtmlElement:
HtmlElement myLocationButton = mapBrowser.Document.GetElementById("mylocation");
myLocationButton.InvokeMember("click");
But, of course neither of these methods actually work correctly, the coordinates returned are incorrent and the map never actually focuses. Any ideas on how I can fix this issue properly? The scripts aren't invoked until after the document is actually loaded:
private void mapBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if(mapBrowser.Url.ToString() == "https://www.google.com/maps/preview/")
{
try
{
//HtmlElement myLocationButton = mapBrowser.Document.GetElementById("mylocation");
//myLocationButton.InvokeMember("click");
mapBrowser.Document.InvokeScript("mylocation.onButtonClick");
//mapBrowser.Document.InvokeScript("focus:mylocation.main");
}
catch (Exception ex)
{
MessageBox.Show("Error Invoking Script: " + ex.Message);
}
}
}
so I don't believe that is the cause of my problem. Even more frustratingly, the auto-focus works fine if I click the button manually.
Any help is appreciated, thank you!
(NOTE, you may have to go into IE and allow Google maps access to your location in order to replicate this issue properly)
I've had problem few times that WebBrowser control uses too old version of IE. You need to modify registry to get it to use newer version of IE.
I tried "https://www.google.com/maps/preview/" with both IE 8 and 9 and it gave me an error, but it works on IE 10.
See: http://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version
You can't have your cake and eat it too, apparently.
I'm currently using the System.Windows.Forms.WebBrowser in my application. The program currently depends on using the GetElementsByTagName function. I use it to gather up all the elements of a certain type (either "input"s or "textarea"s), so I can sort through them and return the value of a specific one. This is the code for that function (my WebBrowser is named web1):
// returns the value from a element.
public String FetchValue(String strTagType, String strName)
{
HtmlElementCollection elems;
HtmlDocument page = web1.Document.Window.Frames[1].Document;
elems = page.GetElementsByTagName(strTagType);
foreach (HtmlElement elem in elems)
{
if (elem.GetAttribute("name") == strName ||
elem.GetAttribute("ref") == strName)
{
if (elem.GetAttribute("value") != null)
{
return elem.GetAttribute("value");
}
}
}
return null;
}
(points to note: the webpage I need to pull from is in a frame, and depending on circumstances, the element's identifying name will be either in the name or the ref attribute)
All of that works like a dream with the System.Windows.Forms.WebBrowser.
But what it is unable to do, is redirect the opening of a new window to remain in the application. Anything that opens in a new window shoots to the user's default browser, thus losing the session. This functionality can be easily fixed with the NewWindow2 event, which System.Windows.Forms.WebBrowser doesn't have.
Now forgive me for being stunned at its absence. I have but recently ditched VB6 and moved on to C# (yes VB6, apparently I am employed under a rock), and in VB6, the WebBrowser possessed both the GetElementsByTagName function and the NewWindow2 event.
The AxSHDocVw.WebBrowser has a NewWindow2 event. It would be more than happy to help me route my new windows to where I need them. The code to do this in THAT WebBrowser is (frmNewWindow being a simple form containing only another WebBrowser called web2 (Dock set to Fill)):
private void web1_NewWindow2(
object sender,
AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)
{
frmNewWindow frmNW = new frmNewWindow();
e.ppDisp = frmNW.web2.Application;
frmNW.web2.RegisterAsBrowser = true;
frmNW.Visible = true;
}
I am unable to produce on my own a way to replicate that function with the underwhelming regular NewWindow event.
I am also unable to figure out how to replicate the FetchValue function I detailed above using the AxSHDocVw.WebBrowser. It appears to go about things in a totally different way and all my knowledge of how to do things is useless.
I know I'm a sick, twisted man for this bizarre fantasy of using these two things in a single application. But can you find it in your heart to help this foolish idealist?
I could no longer rely on the workaround, and had to abandon System.Windows.Forms.WebBrowser. I needed NewWindow2.
I eventually figured out how to accomplish what I needed with the AxWebBrowser. My original post was asking for either a solution for NewWindow2 on the System.Windows.Forms.WebBrowser, or an AxWebBrowser replacement for .GetElementsByTagName. The replacement requires about 4x as much code, but gets the job done. I thought it would be prudent to post my solution, for later Googlers with the same quandary. (also in case there's a better way to have done this)
IHTMLDocument2 webpage = (IHTMLDocument2)webbrowser.Document;
IHTMLFramesCollection2 allframes = webpage.frames;
IHTMLWindow2 targetframe = (IHTMLWindow2)allframes.item("name of target frame");
webpage = (IHTMLDocument2)targetframe.document;
IHTMLElementCollection elements = webpage.all.tags("target tagtype");
foreach (IHTMLElement element in elements)
{
if (elem.getAttribute("name") == strTargetElementName)
{
return element.getAttribute("value");
}
}
The webbrowser.Document is cast into an IHTMLDocument2, then the IHTMLDocument2's frames are put into a IHTMLFramesCollection2, then I cast the specific desired frame into an IHTMLWindow2 (you can choose frame by index # or name), then I cast the frame's .Document member into an IHTMLDocument2 (the originally used one, for convenience sake). From there, the IHTMLDocument2's .all.tags() method is functionally identical to the old WebBrowser.Document.GetElementsByTagName() method, except it requires an IHTMLElementCollection versus an HTMLElementCollection. Then, you can foreach the collection, the individual elements needing to be IHTMLElement, and use .getAttribute to retrieve the attributes. Note that the g is lowercase.
The WebBrowser control can handle the NewWindow event so that new popup windows will be opened in the WebBrowser.
private void webBrowser1_NewWindow(object sender, CancelEventArgs e)
{
// navigate current window to the url
webBrowser1.Navigate(webBrowser1.StatusText);
// cancel the new window opening
e.Cancel = true;
}
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/361b6655-3145-4371-b92c-051c223518f2/
The only solution to this I have seen was a good few years ago now, called csExWb2, now on Google code here.
It gives you an ExWebBrowser control, but with full-on access to all the interfaces and events offered by IE. I used it to get deep and dirty control of elements in a winforms-hosted html editor.
It may be a bit of a leap jumping straight into that, mind.
Can someone explain to me how you would use jeditable with an ASP.NET web form (and C# codebehind). I've got a bit of experience with web forms but not very complicated stuff, and haven't used much jquery before, and this is just puzzling me. I understand how to put it in and attach it to the element you want to be editable, it's what jeditable does when you submit the text field that I don't get. How do you handle that in the webform in order to save the changed text? Hope someone understands my issue... Cheers!
There are lots of ways to handle the POST that jEditable sends. I went with a very simple one. I made a new .aspx file and pointed jEditable to that. In there, you can access the form's POSTed fields with this.Request.Form["..."] to do whatever you intend to do. Here's a snippet:
protected override void OnLoad(EventArgs e)
{
this.Response.Clear();
this.Response.Cache.SetNoStore();
this.Response.Cache.SetExpires(DateTime.Now);
this.Response.StatusCode = 200;
try
{
var postId = this.Request.Form["id"];
var value = this.Request.Form["value"];
this.Response.Write(value);
switch (postId)
{
case "id1":
// write 'value' to DB or whatever
break;
case "id2":
// write 'value' to DB or whatever
break;
default:
this.Response.StatusCode = 501; // Not Implemented
}
this.Response.End();
}
}