تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
استخراج معلومات محددة من جدول html باستعمال HtmlAgilityPack
#1
السلام عليكم 

مرحبا اخواني ,,, انا جديد معكم ,, وحت اني لسى بادء في C# من يومين 

المهم الامر كالتالي :  يوجد صورة + كود 

اني اريد استخراج معلومات محددة من جدول html باستعمال HtmlAgilityPack  
+
مع تبديل ترتيب مصفوفتين عند عرض الناتج 

=====
صورة توضح الامر 


====
هدا كود تجربتي لكن الكود يجلب كل معلومات الجدول وانا اريد معلومات محددة مع تبديل ترتيب مصفوفتين عند عرض الناتج  

كود :
            // Clear Datagridview
            dataGridView1.DataSource = null;
            
            HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();
           
            // Load a file
            html.Load(test.html);
            
           var headers = html.DocumentNode.SelectNodes("//p[4]/table[1]/tr[1]/th");
           DataTable table = new DataTable();
            
            // Create columns from th
           foreach (HtmlNode header in headers)
            {
               table.Columns.Add(header.InnerText);
            }
            
           // Select rows with td elements
           foreach (var row in html.DocumentNode.SelectNodes("//p[4]/table[1]/tr[td]"))
           {
               table.Rows.Add(row.SelectNodes("td").Select(td => td.InnerText).ToArray());
           }
            
            // Show Result
           dataGridView1.DataSource = table;

=====
كود صفحة html 
PHP كود :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml">

<
head>
<
meta content="text/html; charset=utf-8" http-equiv="Content-Type" />

</
head>

<
body>

<
center><font size="+2">Title_Test Title_Test</font></center>
<
p><font size="+1"><b><span class="yyyyyy">2_Title_test&nbsp;</span><font color="#000000">NAME 
PROJET
</font></b></font></p>
<
p>
<
table>
    <
tr>
        <
td><b>Testtable</b></td>
        <
td>:</td>
        <
td>oo</td>
    </
tr>
    <
tr>
        <
td><b>Testtable2TesttableTesttable</b></td>
        <
td>:</td>
        <
td>uu</td>
    </
tr>
    <
tr>
        <
td><b>Testtable3</b></td>
        <
td>:</td>
        <
td>iii</td>
    </
tr>
</
table>
</
p>
<
p><font size="+1"><b><a name="GGGGGGGGG"></a>InfoTest_InfoTest_InfoTest</b></font></p>
<
p><b>testtesttesttesttesttesttesttesttesttest </b>.<br />
<
table border="1" bordercolor="#808080" cellpadding="2">
    <
tr valign="center">
        <
th align="middle">Column0</th>
        <
th align="middle">Column1</th>
        <
th align="middle">Column2</th>
        <
th align="middle">Column3</th>
        <
th align="middle">Column4</th>
        <
th align="middle">Column5</th>
        <
th align="middle">Column6</th>
        <
th align="middle">Column7</th>
    </
tr>
    <
tr valign="center">
        <
td align="left">pola</td>
        <
td align="right">111</td>
        <
td align="right">po111</td>
        <
td align="right">1111</td>
        <
td align="right">po1111</td>
        <
td align="right">NN</td>
        <
td align="right">VV</td>
        <
td align="right">NV</td>
    </
tr>
    <
tr valign="center">
        <
td align="left">yato</td>
        <
td align="right">222</td>
        <
td align="right">ya222</td>
        <
td align="right">2222</td>
        <
td align="right">ya2222</td>
        <
td align="right">NN</td>
        <
td align="right">VV</td>
        <
td align="right">NV</td>
    </
tr>
    <
tr valign="center">
        <
td align="left">romaz</td>
        <
td align="right">333</td>
        <
td align="right">ro333</td>
        <
td align="right">3333</td>
        <
td align="right">ro3333</td>
        <
td align="right">NN</td>
        <
td align="right">VV</td>
        <
td align="right"></td>
    </
tr>
    <
tr valign="center">
        <
td align="left">anik</td>
        <
td align="right">444</td>
        <
td align="right">an444</td>
        <
td align="right">4444</td>
        <
td align="right">an4444</td>
        <
td align="right">NN</td>
        <
td align="right">VV</td>
        <
td align="right"></td>
    </
tr>
    <
tr valign="center">
        <
td align="left">kilwa</td>
        <
td align="right">555</td>
        <
td align="right">ki555</td>
        <
td align="right">5555</td>
        <
td align="right">ki5555</td>
        <
td align="right">NN</td>
        <
td align="right">VV</td>
        <
td align="right"></td>
    </
tr>
    <
tr valign="center">
        <
td align="left">sekil</td>
        <
td align="right">666</td>
        <
td align="right">se666</td>
        <
td align="right">5555</td>
        <
td align="right">se6666</td>
        <
td align="right">NN</td>
        <
td align="right">VV</td>
        <
td align="right"></td>
    </
tr>
    <
tr valign="center">
        <
td align="left">janit</td>
        <
td align="right">777</td>
        <
td align="right">ja777</td>
        <
td align="right">7777</td>
        <
td align="right">ja7777</td>
        <
td align="right">NN</td>
        <
td align="right">VV</td>
        <
td align="right"></td>
    </
tr>
    
</
table>
</
p>

</
body>

</
html

======
لقد شاهدت موضوع الاخ الشاكي لله ,, فيديو الشرح محدوف + اني لم افهم كود المتال جيدا 
موضوع الاخ 
http://vb4arb.com/vb/thread-1623.html

===========
ارجو المساعدة  ,, بتعديل على الاكود او ارفق متال قريب لموضوعي 

في انتظار مروركم 


الرد }}}
تم الشكر بواسطة:
#2
لو مساعدة اصدقائي ؟؟
الرد }}}
تم الشكر بواسطة:
#3
عليكم السلام ورحمة الله وبركاته


ان كنت تستخرج البيانات بشكل صحيح ، اذن لاداعي لتعديل اكواد الاستخراج

تستطيع التعديل على الdatatable مثلا كود الحذف من الdatatable

PHP كود :
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.RemoveAt() 


واما بخصوص اعادة ترتيب اعمدة الdatatable فتوجد الدالة SetOrdinal
PHP كود :
dt.Columns[3].SetOrdinal(2);
dt.Columns[2].SetOrdinal(3); 
الرد }}}
تم الشكر بواسطة:
#4
تم التطبيق على مثالك والكود جاهز وهو كما يلي :

PHP كود :
...
...

           
//remove columns
            
table.Columns.Remove("column7");
            
table.Columns.Remove("column6");
            
table.Columns.Remove("column5");


            
//re-arrange columns
            
table.Columns["column2"].SetOrdinal(3);
            
table.Columns["column3"].SetOrdinal(2);
         

            
// Show Result
            
dataGridView1.DataSource table


دائما اخي عندما تتعامل مع html ، اولا اجلب جميع البيانات (سواء المهمة والغير مهمة).
بعدها قم بادخال البيانات داخل array او datatable او اي collection
بعدها بسهولة يمكنك عمل الفلترة بدوال الدوت نت كما رايت Smile
الرد }}}
تم الشكر بواسطة: Zads10
#5
اسمح لي ان اقوم بإعادة تصوير الفيديو الخاص ب HAPXPathFinder حيث سأقوم ببناء نفس مثالك ولكن سنشرح كيفية التعامل مع HAPXPathFinder لكتابة الكود
الرد }}}
تم الشكر بواسطة: Zads10
#6
(27-12-15, 12:30 AM)الشاكي لله كتب : تم التطبيق على مثالك والكود جاهز وهو كما يلي :

PHP كود :
...
...

 
          //remove columns
 
           table.Columns.Remove("column7");
 
           table.Columns.Remove("column6");
 
           table.Columns.Remove("column5");


 
           //re-arrange columns
 
           table.Columns["column2"].SetOrdinal(3);
 
           table.Columns["column3"].SetOrdinal(2);
 
        

            
// Show Result
 
           dataGridView1.DataSource table


دائما اخي عندما تتعامل مع html ، اولا اجلب جميع البيانات (سواء المهمة والغير مهمة).
بعدها قم بادخال البيانات داخل array او datatable او اي collection
بعدها بسهولة يمكنك عمل الفلترة بدوال الدوت نت كما رايت Smile


بارك الله فيك على تجاوبك 

تفكيرك للحل صراحة ابهرني ,,, لم افكر في الامر ,,,, معك حق استخراج المعلومات html من تم الى array او ,,, تبقى سهلة وعملية وتتعامل بليونة بالمعلومات ,,,,, راح اشتغل بها 

تشكر اخي شاكي لله
,,,

(27-12-15, 12:40 AM)الشاكي لله كتب : اسمح لي ان اقوم بإعادة تصوير الفيديو الخاص ب HAPXPathFinder حيث سأقوم ببناء نفس مثالك ولكن سنشرح كيفية التعامل مع HAPXPathFinder لكتابة الكود


تفضل اخي خد راحتك ,,, انا الي راح اشكرك انك راح تعمل شيء تفيد به الجميع ,,, بارك الله فيك 

=====

بالنسبة للحل لقد  وصلت لحل ,,, لكن طريقة حلك في الرد اعلى احسن ,,, الحل قام بمساعدتي به اخ ,,, وكان حله كالتالي الكود صحيح وشغال... مع بعض الاشكالات لو تعمل لها تحليل في الشرح 

تفضل هدا كود الحل ,,, للافادة 
=====
كود :
       HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();
       // Load a file
       html.Load(@"c:\OneDrive\Work\MS Projects\text.html");      
       HtmlNode table = html.DocumentNode.SelectSingleNode("//table[@border='1']");
       DataTable dt = new DataTable();
       var rows = table.SelectNodes("tr");
       for (int i = 0; i < rows.Count; ++i)
       {
           //if row = then these are headers
           if (i == 0)
           {
               var cols = rows[i].SelectNodes("th");                    
               dt.Columns.Add(new DataColumn(cols[0].InnerText.ToString()));
               dt.Columns.Add(new DataColumn(cols[1].InnerText.ToString()));                    
               dt.Columns.Add(new DataColumn(cols[3].InnerText.ToString()));
               dt.Columns.Add(new DataColumn(cols[2].InnerText.ToString()));
               dt.Columns.Add(new DataColumn(cols[4].InnerText.ToString()));
           }

           //row>0 then data
           else
           {
               var cols = rows[i].SelectNodes("td");

               DataRow dr = dt.NewRow();
               dr[0] = cols[0].InnerText.ToString();
               dr[1] = cols[1].InnerText.ToString();
               dr[2] = cols[3].InnerText.ToString();
               dr[3] = cols[2].InnerText.ToString();
               dr[4] = cols[4].InnerText.ToString();
               dt.Rows.Add(dr);
           }
       }


الكود شغال مع متال صفحة html المرفق ,,, لكن هناك اشكال في كود الحل وهو في XPatch لانه غير عملي لو هناك جداول كتييرة ولها نفس الستايل هدا هو  ,, ("//table[@border='1']")
اتكلم عن هدا السطر 
====

كود :
HtmlNode table = html.DocumentNode.SelectSingleNode("//table[@border='1']")

====
ولما استعملت HAPXPathFinder  وقمت بجلب XPatch  يكون جيد وعملي ("//p[4]/table")  منطقيا كان يجب ان يشتغل لاني جربته في HAPXPathFinder واعطى الناتج  =>  لكن لم يشتغل الكود ,,, 

,,,, لو امكن ان تشير الى الامر في شرحك او  توضحه هنا ,,, لكي تعم الفائدة  ,,,, وهو انه لما  عوضت XPatch الكود  بالــ XPatch التاني ولم يشتغل الكود 

في انتظار مرورك 
,,,,
راح اكتر عليك اخي الشاكي لله ,,, لو لك وقت تمر على هدا الموضوع ,,, 
http://vb4arb.com/vb/thread-14243-post-68107.html

بالتوفيق لكــ 

,,,
الرد }}}
تم الشكر بواسطة: الشاكي لله
#7
^

الxpath لايمكن ان يتشابه معه عنصر اخر مهما حصل

حتى لو كانت هناك جداول مشابهة لبعض لايمكن ان يحصل تشابه في الxpath

الصيغة التي تستعملها لاتسمى xpath اقصد هذه ("//table[@border='1']")

انما انت باستعمالها كانك تقول للدالة ، ابحثي عن الnode المسمى table الذي يحتوي على المواصفة border = 1

وبالفعل ذلك صحيح ان استخدام صيغة البحث باستعمال الnode والمواصفة فاشلة ،

حيث كما قلت اذا تشابه اكثر من عنصر في نفس اسم النود وفي نفس قيمة المواصفة ، طبعا هذا سيحصل لو كان في الصفحة اكثر من جدول ،بالتالي سيحصل تضارب في جلب القيم.

لذلك الحل هو استخدام الxpath وهو string فريد خاص لكل عنصر في الhtml وهو لايتكرر

مثال ل xpath الtable في مثالك ، سيكون :
/html[1]/body[1]/p[4]/table[1]
الرد }}}
تم الشكر بواسطة: Zads10
#8
(27-12-15, 02:40 AM)الشاكي لله كتب : ^

الxpath لايمكن ان يتشابه معه عنصر اخر مهما حصل

حتى لو كانت هناك جداول مشابهة لبعض لايمكن ان يحصل تشابه في الxpath

الصيغة التي تستعملها لاتسمى xpath اقصد هذه  ("//table[@border='1']")

انما انت باستعمالها كانك تقول للدالة ، ابحثي عن الnode المسمى table الذي يحتوي على المواصفة border = 1

وبالفعل ذلك صحيح ان استخدام صيغة البحث باستعمال الnode والمواصفة فاشلة ،

حيث كما قلت اذا تشابه اكثر من عنصر في نفس اسم النود وفي نفس قيمة المواصفة ، طبعا هذا سيحصل لو كان في الصفحة اكثر من جدول ،بالتالي سيحصل تضارب في جلب القيم.

لذلك الحل هو استخدام الxpath وهو string فريد خاص لكل عنصر في الhtml وهو لايتكرر

مثال ل xpath الtable في مثالك ، سيكون :
/html[1]/body[1]/p[4]/table[1]

نعم  هدا الي حصل وقمت بوضع xpath لاجل جعل الامر مضبوط اكتر 

لقد عملت xpath ,, الي وضعت  /html[1]/body[1]/p[4]/table[1]   وهو نفسه الى اشرت له فوق //p[4]/table  (بما انه توجد html و body واحدة في الكودبعد ان جربته وتأكدت منه في اداة HAPXPathFinder ,, الاصدار الاخير  ,,, حسب ما موضح هنا  https://www.youtube.com/watch?v=wsIZgAiH8kg

==== 
بعد ما جربت على الكود المرفق بوضع الxpath  ,,, يطلع مشكل ولا يشتغل 
====
صورة توضيحية





====
لا عليك ,,, راح اشتغل بفكرتك  ,,, حت تضع فديو الشرح وافهم الامر جيدا 
بالتوفيق لكــ  


الرد }}}
تم الشكر بواسطة:
#9
^ جربت الكود عندي وهو يعمل تمام ويقوم بالجلب

يبدو ان المشكلة في المكتبة عندك

هل المكتبة التي يستخدمها برنامجك كRefreance هي نفسها المكتبة التي تستعملها اداة haxxfinder ?

برفق لك المكتبة + الاداة هنا ، الاداة معدلة اصبح بامكانها فتح روابط من سطح المكتب :


الملفات المرفقة
.rar   HAPXPathFinder_v2.rar (الحجم : 51.53 ك ب / التحميلات : 60)
الرد }}}
تم الشكر بواسطة: Zads10 , السندبااد
#10
(27-12-15, 06:55 AM)الشاكي لله كتب : ^ جربت الكود عندي وهو يعمل تمام ويقوم بالجلب

يبدو ان المشكلة في المكتبة عندك

هل المكتبة التي يستخدمها برنامجك كRefreance هي نفسها المكتبة التي تستعملها اداة haxxfinder ?

برفق لك المكتبة + الاداة هنا ، الاداة معدلة اصبح بامكانها فتح روابط من سطح المكتب :


معك حق كانت المشكلة من المكتبة كنت احملها مباشرة من مركز محرر .net 

بعد استعمال المكتبة المرفقة اشتغل الامر 

الف شكـــــررررر  اخي  الشاكي لله
الرد }}}
تم الشكر بواسطة:



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم