这一篇将说明如何使用C#和WPF浏览器控件来完成淘宝自动搜索,翻页,自动点击的操作
首先说明下,我在实现过程中使用的控件,一个是浏览器WebBrowser,一个是按钮Button,还有单选按钮RadioButton,以及多选CheckBox,下文代码中的reload函数是重新加载页面的函数。
目录
这个软件设计的手动操作部分如下
1.自动填写搜索栏
先是实例化HTMLDocument,HTMLDocument类会获取目前浏览器控件加载好的网页文档,提供之后IHTMLElementCollection进行元素查找和操作。
尽管这部分函数我设计为按钮触发,但为了防止没有加载好的时候就获取,需要先等待网页加载完毕
if (webbrowser.IsLoaded != true)
{
InfoAdd("搜索前请先等待页面完成加载");
return;
}
其中webbrowser是我们WPF的浏览器控件名称,如果加载完成,那么可以实例化HTMLDocument
HTMLDocument doc = webbrowser.Document as HTMLDocument;
接下来我们可以看看淘宝的主页,顶部的搜索栏的HTML文本结构,这里可以使用浏览器调试模式查看,点击F12即可
可以看到,标签是input,因此,接下来我们要获取网页中所有的input标签,并且遍历搜索,找到搜索文本的输入框,并且将我需要的内容输入进去
//实例化元素搜集用途的类,然后弄一个页面上所有input标签的集合
IHTMLElementCollection els = doc.getElementsByTagName("input");
//遍历查找我们需要的那个搜索输入框
foreach (IHTMLElement em in els)
{
try
{
i++;
if (em.id != null)
{
if (em.id.Contains("q"))
{
//tbSearchWord.Text是一个控件,填写我需要填入淘宝搜索栏的文本
em.setAttribute("value", tbSearchWord.Text);
}
}
}
catch
{
}
}
获取淘宝页面中的搜索栏,并且自动填写文本就实现了
2.自动点击搜索按钮的实现
和上一步一样的步骤,打开网页调试窗口,可以看到搜索按钮是button标签,所以我们一样获取下button元素
IHTMLElementCollection els2 = doc.getElementsByTagName("button");
然后一样是遍历获取到的按钮,因为按钮中有文本所以我们通过比对innerText即可获取到
foreach (IHTMLElement em in els2)
{
try
{
if (em.innerText != null)
{
if (em.innerText.Contains("搜索"))
{
em.click();
}
}
}
catch
{
}
finally
{
}
}
搜索+点击搜索按钮的函数(无注释版本)
void function2() //auto input
{
int i = 0;
if (webbrowser.IsLoaded != true)
{
InfoAdd("搜索前请先等待页面完成加载");
return;
}
HTMLDocument doc = webbrowser.Document as HTMLDocument;
IHTMLElementCollection els = doc.getElementsByTagName("input");
foreach (IHTMLElement em in els)
{
try
{
i++;
if (em.id != null)
{
if (em.id.Contains("q"))
{
em.setAttribute("value", tbSearchWord.Text);
}
}
}
catch
{
}
}
Thread.Sleep(200);
IHTMLElementCollection els2 = doc.getElementsByTagName("button");
foreach (IHTMLElement em in els2)
{
try
{
if (em.innerText != null)
{
if (em.innerText.Contains("搜索"))
{
em.click();
}
}
}
catch
{
}
finally
{
}
}
// System.Windows.MessageBox.Show("Current:"+i);
}
3.翻页的实现
翻页是对于整个网站结构的推测,例如,我先随便搜索什么东西,跳转页面结果后,网址是
这里面并没有包含页面的信息,滑动到网页末尾,点击第二页
可以看到,末尾有一个s=44
通过修改,可以了解,这部分是商品显示的序号,一页显示43个商品,那么s=44就是说,从第44个开始显示
可以试试,s=0 搜索页面末尾的结果
当s=41时
这里让我有点奇怪的是,一页显示是43个,那么最后一个应该是42(因为是从0开始),但这边却是41
不过,依据以上的方法也就基本可以搞懂搜索结果页面翻页的原理了
先获取网页的连接,判断现在的页面是翻页后的页面(有s=)还是没有翻页的页面如果说当前页面不是翻页后的页面,那么就在末尾添加标识,请求下一页的44个商品
tbAddress.Text = webbrowser.Source.AbsoluteUri;
string currentUri = tbAddress.Text;
if (currentUri.Contains("ie=utf8") && !currentUri.Contains("&s="))
{
InfoAdd("当前是搜索结果页面首页");
InfoAdd("尝试跳转到第2页");
reload(currentUri + "&s=44");
return 2;
}
如果是翻页的页面,就获取s=的值,以判断当前第几页,算法只是操作字符串,所以就不做详述了。函数会返回当前的页面是搜索结果的第几页
else if (currentUri.Contains("&s="))
{
InfoAdd("尝试跳转到下一页");
string rebuilds = "";
string[] s = currentUri.Split('=');
s[s.Length - 1] = (Convert.ToInt32(s[s.Length - 1]) + 44).ToString();
for (int i = 0; i < s.Length; i++)
{
if (i != 0) rebuilds += "=";
rebuilds += s[i];
}
int currentpage = (Convert.ToInt32(s[s.Length - 1])) / 44 + 1;
InfoAdd("当前页为第" + currentpage.ToString() + "页");
reload(rebuilds);
// System.Windows.MessageBox.Show("RebuildUrl:" + rebuilds);
return currentpage;
}
翻页部分的整个函数
由按钮触发,自定义的控件有tbNextPage, tbAddress, webbrowser
private void tbNextPage_Click(object sender, RoutedEventArgs e)
{
GoToNextPage();
}
/// <summary>
/// 寻找下一页按钮并跳转
/// </summary>
/// <returns>跳转后的页面是第几页</returns>
private int GoToNextPage()
{
tbAddress.Text = webbrowser.Source.AbsoluteUri;
string currentUri = tbAddress.Text;
if (currentUri.Contains("ie=utf8") && !currentUri.Contains("&s="))
{
InfoAdd("当前是搜索结果页面首页");
InfoAdd("尝试跳转到第2页");
reload(currentUri + "&s=44");
return 2;
}
else if (currentUri.Contains("&s="))
{
InfoAdd("尝试跳转到下一页");
string rebuilds = "";
string[] s = currentUri.Split('=');
s[s.Length - 1] = (Convert.ToInt32(s[s.Length - 1]) + 44).ToString();
for (int i = 0; i < s.Length; i++)
{
if (i != 0) rebuilds += "=";
rebuilds += s[i];
}
int currentpage = (Convert.ToInt32(s[s.Length - 1])) / 44 + 1;
InfoAdd("当前页为第" + currentpage.ToString() + "页");
reload(rebuilds);
// System.Windows.MessageBox.Show("RebuildUrl:" + rebuilds);
return currentpage;
}
return 0; //当前页面不可跳转
}
4.匹配名称和ID并点击商品
商品连接就是普通的连接,在淘宝的页面中是以a标签标注的,所以,依照先前的部分一样,我们需要实例化并且获取到所有的a标签元素
HTMLDocument doc = webbrowser.Document as HTMLDocument;
IHTMLElementCollection allurl = doc.getElementsByTagName("a");
然后就是对获取到的a标签进行筛选,获取到目标,有一点是,天猫,推荐和普通商品这三种,连接的服务器名部分是不一样的
foreach (IHTMLElement em in allurl)
{
string url = em.getAttribute("href");
if (url == null) continue;
string[] sarr = url.Split(new char[] { '/' });
if (sarr.Length < 3) continue;
string s = url.Split(new char[] { '/' })[2].Split(new char[] { '.' })[0];
string name = em.innerText;
//普通被勾选
if (cbItem.IsChecked == true && cbDetail.IsChecked == false && cbClick.IsChecked == false)
{
if (s.Equals("detail") || s.Equals("item"))
{
if (name != null && name.Contains("销量") == false && name.Contains("¥") == false && name.Contains(".00") == false)
{
tbaddressinfo.Text += url + "\r\n";
if (name.Length > 2)
{
if (name.Contains(targetname) || name.Contains(targetname.Substring(0, targetname.Length - 1)) )
{
if(url.Contains(tbTargetID.Text))
{
reload(url);
finded = true;
break;
}
}
}
}
}
}
通过上面的算法就可以选出我们需要的物品的名称以及连接,最后一步的判断有一个匹配TargetID的部分
if(url.Contains(tbTargetID.Text))
{
reload(url);
finded = true;
break;
}
其中这里的tbTargetID是指的一件商品独有的ID,因为只搜索商品名称,有可能会有重复的问题,所以建议加上该部分判断
如果还有不了解的请在评论中留言