This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's Calculator Programming subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. General Coding and Design => Calculator Programming
Author Message
Newbie


Bandwidth Hog


Joined: 23 Jan 2004
Posts: 2247

Posted: 10 May 2008 03:19:04 pm    Post subject:

Does anyone know how I might use Visual Basic or C#.Net to automate the process of filling out a form on a website and then submitting it?
Back to top
Weregoose
Authentic INTJ


Super Elite (Last Title)


Joined: 25 Nov 2004
Posts: 3976

Posted: 10 May 2008 03:49:24 pm    Post subject:

The Autofill Forms extension for Firefox will allow you to customize what fields to fill out automatically, along with a surplus of other options (see screenshot). About submitting automatically, I dunno. A keyboard/mouse macro would do the work just fine – I used one to upload hundreds of files to the TI|BD.

Last edited by Guest on 10 May 2008 03:51:29 pm; edited 1 time in total
Back to top
magicdanw
pcGuru()


Calc Guru


Joined: 14 Feb 2007
Posts: 1110

Posted: 10 May 2008 04:05:05 pm    Post subject:

Take a look at this page for information about using the VB SendKeys function to send keypresses to another application.
Back to top
benryves


Active Member


Joined: 23 Feb 2006
Posts: 564

Posted: 10 May 2008 07:18:24 pm    Post subject:

A rather less Heath Robinson approach would be to use the WebRequest class.

Here's a quick-and-dirty demo that sends a POST request to rot13.com.

Code:
using System.IO;
using System.Net;
using System.Text;

namespace PostWebRequestDemo {
    class Program {
        static void Main(string[] args) {
            
            // Create a WebRequest instance to perform the query.
            var Request = WebRequest.Create("http://www.rot13.com/");
            Request.Method = "POST";
            Request.ContentType = "application/x-www-form-urlencoded";

            // Here's the parameter (just the one).
            var RequestParams = "text=P+funec+naq+.ARG+ner+pbby,+ab?";
            Request.ContentLength = RequestParams.Length;

            // Write our request.
            using (var RequestStreamWriter = new StreamWriter(Request.GetRequestStream(), Encoding.Default)) {
                RequestStreamWriter.Write(RequestParams);
            }

            // Execute/Read the response.
            string Response = "";
            using (var ResponseReader = new StreamReader(Request.GetResponse().GetResponseStream())) {
                Response = ResponseReader.ReadToEnd();
            }

        }
    }
}
Another option might be to use the DOM methods exposed by the WebBrowser control.

Last edited by Guest on 10 May 2008 07:19:46 pm; edited 1 time in total
Back to top
Newbie


Bandwidth Hog


Joined: 23 Jan 2004
Posts: 2247

Posted: 10 May 2008 07:35:29 pm    Post subject:

Thanks a lot for your help. I'm going to try benryves solution first and see what happens. I'll get back to you on how it went.


Edit:
benryves, your solution worked great, well after adding

Console.WriteLine(Response);
Console.ReadLine();

so I could read the results. LOL Smile

Your solution uses one field. How do I go about a form that has multiple fields, by knowing which field to write to?

Sorry, I'm not real familiar with the console part of C#, I normally deal with a form.


Last edited by Guest on 10 May 2008 07:59:10 pm; edited 1 time in total
Back to top
calc84maniac


Elite


Joined: 22 Jan 2007
Posts: 770

Posted: 10 May 2008 08:11:07 pm    Post subject:

Here's an idea that sounds really neat (and has been suggested before): A program that will automatically log in on each TI site you choose and post the same topic (or post in the same topic) in each of them, thus making it way easier to post updates on projects that are on multiple forums, and aren't run-on sentences fun?
Back to top
benryves


Active Member


Joined: 23 Feb 2006
Posts: 564

Posted: 10 May 2008 08:17:56 pm    Post subject:

Newbie wrote:
...so I could read the results. LOL  Smile
Heh, I usually set a breakpoint on the closing brace of the Main method so I can hover the variables to see their state. Either way, glad you got it working!

Quote:
Your solution uses one field. How do I go about a form that has multiple fields, by knowing which field to write to?
Oops, I probably should have mentioned that. You might have noticed the "application/x-www-form-urlencoded" content-type; this means you pass the field variables like this:


Code:
field1=value1&field2=value2&field3=value3&field4=value4

(And so on and so forth). You need to make sure that the values you are passing are suitably encoded for passing via an URL (in my above example, the spaces were replaced with the + sign). Fortunately .NET provides a method to do this for us, but you will need to add a reference to System.Web to your project settings. Then you can do this:

Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;

namespace PostWebRequestDemo {
    class Program {
        static void Main(string[] args) {

            // Here are the fields to submit.
            var Fields = new Dictionary<string, string>();
            Fields.Add("text", "P funec naq .ARG ner pbby, ab?" + Environment.NewLine + "Abgr ubj guvf vf pbeerpgyl HEY-rapbqrq.");
            Fields.Add("other", "There is no other field, but let's pretend!");
    
            // Create a WebRequest instance to perform the query.
            var Request = WebRequest.Create("http://www.rot13.com/");
            Request.Method = "POST";
            Request.ContentType = "application/x-www-form-urlencoded";

            // Turn fields into a query string.
            var RequestParams = CreateQueryString(Fields);
            Request.ContentLength = RequestParams.Length;

            // Write our request.
            using (var RequestStreamWriter = new StreamWriter(Request.GetRequestStream(), Encoding.Default)) {
                RequestStreamWriter.Write(RequestParams);
            }

            // Execute/Read the response.
            string Response = "";
            using (var ResponseReader = new StreamReader(Request.GetResponse().GetResponseStream())) {
                Response = ResponseReader.ReadToEnd();
            }

            

        }

        private static string CreateQueryString(IEnumerable<KeyValuePair<string, string>> fields) {
            var EncodedFields = new List<string>();
            foreach (var Field in fields) {
                EncodedFields.Add(HttpUtility.UrlEncode(Field.Key) + "=" + HttpUtility.UrlEncode(Field.Value));
            }
            return string.Join("&", EncodedFields.ToArray());
        }

    }
}


Last edited by Guest on 10 May 2008 08:22:08 pm; edited 1 time in total
Back to top
Newbie


Bandwidth Hog


Joined: 23 Jan 2004
Posts: 2247

Posted: 10 May 2008 08:24:58 pm    Post subject:

So from what I'm seeing you don't really need to know the field names that the website uses, it's done in chronological order? For instance the first field.add would write to the first field on the form and the second to the second and so forth?

Edit: One last question. Do you know how to deal with an option on a form that would be a drop down list of items?

I really appreciate your help.


Last edited by Guest on 10 May 2008 08:31:33 pm; edited 1 time in total
Back to top
benryves


Active Member


Joined: 23 Feb 2006
Posts: 564

Posted: 10 May 2008 08:48:30 pm    Post subject:

Newbie wrote:
So from what I'm seeing you don't really need to know the field names that the website uses, it's done in chronological order?
No, you must explicitly pass the name of the form fields. You can get these by viewing the page source. Depending on how the way the page is written, you might not need to pass all of them, and you can probably pass extra ones, but you do need to use the name in the HTML source (including the case!) If you view the source for the rot13.com page, you'll see a <textarea> named "text".

Quote:
Edit: One last question. Do you know how to deal with an option on a form that would be a drop down list of items?
Find the corresponding <select> element, and it will contain a number of <option> elements. For example:


Code:
<select name="boris">
    <option value="1">Spaghetti</option>
    <option value="2">Glass</option>
    <option value="3">Piano</option>
</select>

To pass "Glass" I would need to do this:

Code:
Fields.Add("boris", "2");


Checkboxes are more interesting; to submit a checkbox that is checked, pass its name and its value. If it is unchecked, do not pass it at all.

If you need to work out these details at runtime, you would need to parse the original HTML form somehow. This is a non-trivial operation if you wish to do it properly, though it is made easier via the WebBrowser.Document's DOM methods.
Back to top
Newbie


Bandwidth Hog


Joined: 23 Jan 2004
Posts: 2247

Posted: 10 May 2008 08:53:51 pm    Post subject:

Oh, I see how it works now. I thought the text meant the type of information you were trying to pass. Thanks a lot for your help, you cleared a lot of things up for me.


Edit:
I get an error: The name 'HttpUtility' does not exist in the current context.

Yeah um, I have the System.Web reference at the top and yet for some reason I get a compile error because of HttpUtility. Weird.

Also on this line: var Fields = new Dictionary<string, string>(); How is the select element added to that? I'm assuming that it would affect the CreateQueryString method too?


Last edited by Guest on 10 May 2008 09:30:12 pm; edited 1 time in total
Back to top
benryves


Active Member


Joined: 23 Feb 2006
Posts: 564

Posted: 11 May 2008 06:38:10 am    Post subject:

Newbie wrote:
I get an error: The name 'HttpUtility' does not exist in the current context.
As I mentioned, you need to add System.Web as a reference to your project. Go Project->Add Reference, select System.Web from the .NET tab, and that should resolve your compile errors.

Quote:
Also on this line: var Fields = new Dictionary<string, string>(); How is the select element added to that? I'm assuming that it would affect the CreateQueryString method too?
"Fields" is a dictionary mapping strings->strings. The CreateQueryString method takes an IEnumerable<KeyValuePair<string, string>> - ie, anything that can be enumerated over to retrieve string->string key->value pairs (which Dictionary<string, string> supports). It could as easily be a KeyValuePair<string, string>[] or a List<KeyValuePair<string, string>>, as these also implement IEnumerable<string, string>.

In any case, you'd just keep adding fields like this:

Code:
Fields.Add("text", "P funec naq .ARG ner pbby, ab?" + Environment.NewLine + "Abgr ubj guvf vf pbeerpgyl HEY-rapbqrq.");
Fields.Add("other", "There is no other field, but let's pretend!");
Fields.Add("boris", "2");
Fields.Add("checkbox1", "ON");
Fields.Add("username", "a.n.other");
// ... and so on. :) Note that this would throw an exception:
Fields.Add("other", "uh-oh");
// ... as the key "other" already exists in the dictionary!
Back to top
Newbie


Bandwidth Hog


Joined: 23 Jan 2004
Posts: 2247

Posted: 11 May 2008 06:39:01 pm    Post subject:

Thanks a lot for your help benryves.
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    »
» View previous topic :: View next topic  
Page 1 of 1 » All times are UTC - 5 Hours

 

Advertisement