PDA

View Full Version : سوال: استخراج یک کلمه از صفحه HTML



mahdishahidi
پنج شنبه 23 آذر 1396, 23:53 عصر
سلام دوستان
من میخوام برنامه ای بنویسم که مثلا شما بهش ID تاپیک رو بدین و بیاد میزان پست های کابر رو بده توی یک textbox (فکر کنید فقط یک کاربر داشته باشیم)
من این روش رومیدونم:


WebClient webpage = new WebClient();
String html = webpage.DownloadString("http://barnamenevis.org/showthread.php?" + textBox1.Text);
MatchCollection match = Regex.Matches(html, FILTERHERE, RegexOptions.Singleline);


الان مشکل ایجاست که نمیدونم چطوری باید فیلتر کنم (FILTERHERE)
بعد هم این که چطوری باید مقدار رو توی textbox بریزم؟

mahdishahidi
جمعه 24 آذر 1396, 22:48 عصر
لطفا اگر کسی پاسخ رو بلده بگه

ramtinak
شنبه 25 آذر 1396, 11:49 صبح
سلام، اول اینکه از عبارات با قاعده برای HTML استفاده نمیکنن.
شما میتونید از کتابخانه HtmlAgilityPack که مخصوص HTML هست و توی تمامی نسخه های دات نت موجود هست استفاده کنید.
یه روش دیگه ای هم هست که من به جای استفاده از روش بالا ازش استفاده می کنم، این هست: از طریق Split و IndexOf و Substring کردن هست که همینو میگم:


خب به کار نمیاد که فقط تعداد پست تنها رو گرفت، باید نام کاربری رو هم گرفت!
خب یک کلاس به اسم User ایجاد میکنیم:

public class User
{
public string Name { get; set; }
public string PostCount { get; set; }
}


خب شما باید کمی از Html سر در بیارید تا بفهمید من چیکار کردم، من خودم هر جاش نیاز دیدم، براتون کامنت نوشتم:
// aval inke " ro ba ' replace mikonim chon sade tar mishe karemon
html = html.Replace(""", "'");




// bayad <div class='userinfo'> ro split konim
// in code html bala ro man az html hamin safhe ei ke post dadi dar avordam
// in tag marbot be usere karbarie
// tamame etelaati ke az user mishe gereft dakhele hamin tag hast
// pas niaz darim hamin ro split konim, injori kole kasaei ke tuye safhe
// post gozashtan ro migirim
var splitedList = new List<string>(html.Split(new string[]
{
"<div class='userinfo'"
}, StringSplitOptions.RemoveEmptyEntries));
// chon injori split miad ye bar az meghdare 0 ta ghabl az
// <div class='userinfo'> ro migire, ma be item e sefrom niazi nadarim
// oas pakesh mikonim
if (splitedList.Count > 0)
splitedList.RemoveAt(0);
// ye listi az classi ke eijad kardim dorost mikonim
// chon maghadire be dast omade ro mikhaim be sorate list dashte bashim
// chon nemidonim chandta user hast!
var List = new List<User>();
foreach(var item in splitedList)
{
string name = string.Empty, count = string.Empty;


//<a class='username offline popupctrl' href='member.php?377161-mahdishahidi' title='mahdishahidi آفلاین است' id='yui-gen19'><strong>mahdishahidi</strong></a>
if (item.Contains("href='"))
{
// vase substring kardan niaz hast ye start Tag dashte bashim,
// ye done ham end tag, yani yeki az jaei ke mikhaim shoro beshe
// yeki ham ta jaei ke mikhaim tamom she
var start = "href='";
var end = "'";


// miaim item ro az href=' + lengthesh mishe tedade karakterhaye
// href=' ke mishe 6 karakter migirim
name = item.Substring(item.IndexOf(start) + start.Length);
// hala az karaktere sefrom ta ' ro migirim, inja chon niazi
// be khode ' nadarim, dige +1 ya + end.Length ro neminevisim
name = name.Substring(0, name.IndexOf(end));
// alan user ro in shekli migire, ama ma faghat esme taraf ro
// mikhaim, pas bayad dobare substring konim
// alan chon ta inja ro nemikhaim=> member.php?377161-
// miaim az karaktere - be bad ro migirim
//member.php?377161-mahdishahidi
name = name.Substring(name.IndexOf("-") + 1);
// chon html mamolan encode mishan, ma niaz hast oun ro decode
// konim, (escape va unescape ham be in kar migan)
name = System.Net.WebUtility.HtmlDecode(name);
}
//<dt>پست</dt> <dd>30</dd>
if (item.Contains("<dt>پست"))
{
// inja ham hamon tozihate bala
var start = "<dt>پست";
var end = "</dd>";


count = item.Substring(item.IndexOf(start) + start.Length);
count = count.Substring(0, count.IndexOf(end));
//<dd>30
start = "<dd>";
count = count.Substring(count.IndexOf(start) + start.Length);
count = System.Net.WebUtility.HtmlDecode(count);
}
// age name va count khaali ya null nabodan
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(count))
{
// age dakhele listemon esmi ba esmi ke alan gereftim barabar nabod
// badesh etelaat jadid ro be list ezafe mikonim
// methode Any ye extension method hast vase inke biad barat
// bayad fazaye nami zir ro benevisi:
// using System.Linq;
if (!List.Any(u => u.Name.ToString() == name))
{
// be list etelaat ro add mikonim
List.Add(new User
{
Name = name,
PostCount = count
});
}
}
}
// inam tarighe estefade
foreach (var item in List)
richTextBox1.Text += item.Name + "\t" + item.PostCount + "\r\n";


و اینطوری نمایش میده:
mahdishahidi 30MMR_1234 132
danialafshari 2,418
Hadi-Hashemi 151


موفق باشید.

mahdishahidi
شنبه 25 آذر 1396, 12:30 عصر
سپاس
میشه با HtmlAgilityPack هم توضیح بدید همینجوری؟
با nuget گرفتمش

پ.ن: توی خط اول html = html.Replace(""", "'"); ارور داره:
Syntax error, ',' expected

من تا اینجا اومدم:

string patch = "http://barnamenevis.org/showthread.php?544768";
System.IO.StreamReader thefile = new System.IO.StreamReader(patch);
string content = thefile.ReadToEnd();
thefile.Close();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(content);
var mydiv = doc.DocumentNode.SelectNodes("");
textBox1.Text = mydiv.InnerText;


ولی خط اخر ارور داره نمیدونم چطوری درستش کنم

mahdishahidi
یک شنبه 26 آذر 1396, 00:48 صبح
کسی هست درمورد HtmlAgilityPack بهم کمک کنه؟

ژیار رحیمی
یک شنبه 26 آذر 1396, 01:07 صبح
سپاس
میشه با HtmlAgilityPack هم توضیح بدید همینجوری؟
با nuget گرفتمش

پ.ن: توی خط اول html = html.Replace(""", "'"); ارور داره:
Syntax error, ',' expected

من تا اینجا اومدم:

string patch = "http://barnamenevis.org/showthread.php?544768";
System.IO.StreamReader thefile = new System.IO.StreamReader(patch);
string content = thefile.ReadToEnd();
thefile.Close();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(content);
var mydiv = doc.DocumentNode.SelectNodes("");
textBox1.Text = mydiv.InnerText;


ولی خط اخر ارور داره نمیدونم چطوری درستش کنم

کدها رو اشتباه نوشتی.کجای کار با HtmlAgilityPack مشکل داری؟

ژیار رحیمی
یک شنبه 26 آذر 1396, 01:25 صبح
private void ReadPage(string url)
{


var client = new WebClient{Encoding = Encoding.UTF8};
client.Headers.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
var htmlDoc = new HtmlAgilityPack.HtmlDocument
{
OptionCheckSyntax = true,
OptionFixNestedTags = true,
OptionAutoCloseOnEnd = true,
OptionDefaultStreamEncoding = Encoding.UTF8
};
client.DownloadStringCompleted += (sender, e) =>
{


try
{
htmlDoc.LoadHtml(e.Result);
GetText(htmlDoc);
}
catch (Exception ex)
{
// ignored
}
};


client.DownloadStringAsync(new Uri(url));
}


private void GetText(HtmlAgilityPack.HtmlDocument doc)
{


if (doc == null) return;
//خواندن تگ از صفحه html
//xpath
var title= doc.DocumentNode.SelectSingleNode("//*[@id='post_2384389']/div[2]/div[2]/div[1]/h2")?.InnerText;
//selector
//var title= doc.DocumentNode.SelectSingleNode("#post_2384389 > div.postdetails > div.postbody > div.postrow > h2")?.InnerText;
MessageBox.Show(title);
}
//فراخوانی متد
ReadPage("http://barnamenevis.org/showthread.php?544768");

mahdishahidi
یک شنبه 26 آذر 1396, 15:24 عصر
کدها رو اشتباه نوشتی.کجای کار با HtmlAgilityPack مشکل داری؟

مشکل حل شد:

string url = "http://barnamenevis.org/showthread.php?";
var web = new HtmlWeb();
var doc = web.Load(url + textBox1.Text);
var tag = doc.DocumentNode.SelectSingleNode("/html[@id='vbulletin_html']/body/div[@class='body_wrapper']/div[@id='postlist']/ol[@id='posts']/li[@id='post_2384517']/div[@class='postdetails']/div[@class='userinfo']/dl[@class='userinfo_extra']/dd[1]");
textBox2.Text = tag.InnerText;

اما الان یک مشکل دیگه هست..
وقتی از برنامه استفاده میکنم پبجره برای چندلحظه هنگ میکنه و غیرقابل استفاده میشه
چطوری میشه از async توی این کد استفاده کرد و این مشکل رو حل کرد؟

ژیار رحیمی
یک شنبه 26 آذر 1396, 18:11 عصر
void ReadPage()
{
string url = "http://barnamenevis.org/showthread.php?";
var web = new HtmlWeb();
var doc = web.Load(url + textBox1.Text);
if(doc==null)return;
var tag = doc.DocumentNode.SelectSingleNode("/html[@id='vbulletin_html']/body/div[@class='body_wrapper']/div[@id='postlist']/ol[@id='posts']/li[@id='post_2384517']/div[@class='postdetails']/div[@class='userinfo']/dl[@class='userinfo_extra']/dd[1]");
if(tag==null) return;
Invoke((MethodInvoker) delegate
{
textBox2.Text = tag.InnerText;
}
}


//فراخوانی
Task.Factory.StartNew(ReadPage);

mahdishahidi
یک شنبه 26 آذر 1396, 22:39 عصر
سپاس
اگر بخوام از توی همون صفحه Element های بیشتری رو استخراج کنم باید چه تغییراتی توی کد بدم؟

ژیار رحیمی
دوشنبه 27 آذر 1396, 04:14 صبح
var tag = doc.DocumentNode.SelectSingleNode("/html[@id='vbulletin_html']/body/div[@class='body_wrapper']/div[@id='postlist']/ol[@id='posts']/li[@id='post_2384517']/div[@class='postdetails']/div[@class='userinfo']/dl[@class='userinfo_extra']/dd[1]");
if(tag!=null)
Invoke((MethodInvoker) delegate
{
textBox2.Text = tag.InnerText;
});
// Second Tag
tag = doc.DocumentNode.SelectSingleNode("/html[@id='vbulletin_html']/body/div[@class='body_wrapper']/div[@id='postlist']/ol[@id='posts']/li[@id='post_2384517']/div[@class='postdetails']/div[@class='userinfo']/dl[@class='userinfo_extra']/dd[2]");
if(tag!=null)
Invoke((MethodInvoker) delegate
{
textBox3.Text = tag.InnerText;
});
// Third Tag
tag = doc.DocumentNode.SelectSingleNode("/html[@id='vbulletin_html']/body/div[@class='body_wrapper']/div[@id='postlist']/ol[@id='posts']/li[@id='post_2384517']/div[@class='postdetails']/div[@class='userinfo']/dl[@class='userinfo_extra']/dd[3]");
if(tag!=null)
Invoke((MethodInvoker) delegate
{
textBox4.Text = tag.InnerText;
});

mahdishahidi
دوشنبه 27 آذر 1396, 19:47 عصر
ارورداد:
) expected
; expected


147293

ژیار رحیمی
دوشنبه 27 آذر 1396, 21:48 عصر
مشکل خاصی نداره خطای جا افتادن ;( در کد هست.پست قبلی اصلاح شد