2016-08-27 16 views
0

私はウェブサイトを削っています。他のプロジェクトでこれを達成しましたが、この権利を得ることはできません。それは2日以上働いていて、何かが足りなくなっているかもしれません。誰かが私のコードを見ることができますか?ここでは、次のとおりです。ウェブサイトをスクラップする

using System; 
using System.Collections.Generic; 
using HtmlAgilityPack; 
using System.Net; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Linq; 
using System.Xml.Linq; 
using System.IO; 

public partial class _Default : System.Web.UI.Page 
{ 
    List<string> names = new List<string>(); 
    List<string> address = new List<string>(); 
    List<string> number = new List<string>(); 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     string url = "http://www.scoot.co.uk/find/" + "cafe" + " " + "-in-uk?page=" + "4"; 
     var Webget = new HtmlWeb(); 
     var doc = Webget.Load(url); 
     List<List<string>> mainList = new List<List<string>>(); 

     foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//h2//a")) 
     { 
      names.Add(Regex.Replace(node.ChildNodes[0].InnerHtml, @"\s{2,}", " ")); 
     } 
     foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//p[@class='result-address']")) 
     { 
      address.Add(Regex.Replace(node.ChildNodes[0].InnerHtml, @"\s{2,}", " ")); 
     } 
     foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//p[@class='result-number']")) 
     { 
      number.Add(Regex.Replace(node.ChildNodes[0].InnerHtml, @"\s{2,}", " ")); 
     } 

     XDocument doccy = new XDocument(

new XDeclaration("1.0", "utf-8", "yes"), 

new XComment("Business For Sale"), 

new XElement("Data", 

from data in mainList 
select new XElement("data", new XAttribute("data", "data"), 
new XElement("Name : ", names[0]), 
new XElement("Add : ", address[0]), 
new XElement("Number : ", number[0]) 
) 
) 

); 

     var xml = doccy.ToString(); 

     Response.ContentType = "text/xml"; //Must be 'text/xml' 
     Response.ContentEncoding = System.Text.Encoding.UTF8; //We'd like UTF-8 
     doccy.Save(Response.Output); //Save to the text-writer 

    } 

} 

ウェブサイトのリストの事業名、電話番号や住所、それらはすべて、クラス名によって定義されます(その結果、アドレス、結果-番号など)。私は明日のプレゼンテーションのために4ページの各リストからビジネス名、住所、電話番号を得ることができるようにXML出力を得ようとしていますが、それはまったく動作しません!

結果は各ループの3つすべてに含まれていますが、xmlに出力されないため、範囲外のエラーが発生します。

+0

これは4つのループのすべてでリストを取得していますが、xmlobjectsにまとめると思います。私は個別のオブジェクトとして存在し、それらすべてを取得することができますが、私はそれを言うのは難しいいくつかのサンプルのhtmlなしで、それは名前、住所、PNUM名、住所、PNUMなどではなく、住所 PNUM

+0

する必要があります通常、各リスティングには共通の親要素があります。私は、共通の親要素を選択し、その上のforeachノードを行うことをお勧めします。次に、内部ノードを選択し、個別の値を1つずつ取得します。これにより、カスタムオブジェクトを定義し、XMLにシリアライズしやすいカスタムオブジェクトを作成することができます。本当に直接的な答えではありませんが、私は申し訳ありませんが、別のアプローチかもしれません。 –

+0

HTMLページのURLは、コード全体にたくさん追加された理由です。 –

答えて

1

私の最初のアドバイスは、CodeBehindを可能な限り軽く保つことです。ビジネスロジックでそれを膨らませると、ソリューションは維持するのが難しくなります。これは話題にはなりませんが、私はソリッドの原則を調べることをお勧めします。

まず、私はアドレス項目がどの名前でアップリンクする知る方法はありません文字列のリストを使用するのではなく、で動作するようにカスタムオブジェクトを作成しました:ここ

public class Listing 
{ 
    public string Name { get; set; } 
    public string Address { get; set; } 
    public string Number { get; set; } 
} 

それの心臓部であります、すべてのスクレーピングとシリアライズが(私はSOLID原則を破ってきましたが、時にはあなたはちょうどそれが右の仕事をしたい。)んクラス

using System.Collections.Generic; 
using HtmlAgilityPack; 
using System.IO; 
using System.Xml; 
using System.Xml.Serialization; 
using System.Linq; 
public class TheScraper 
{ 
    public List<Listing> DoTheScrape(int pageNumber) 
    { 
     List<Listing> result = new List<Listing>(); 

     string url = "http://www.scoot.co.uk/find/" + "cafe" + " " + "-in-uk?page=" + pageNumber; 

     var Webget = new HtmlWeb(); 
     var doc = Webget.Load(url); 

     // select top level node, this is the closest we can get to the elements in which all the listings are a child of. 
     var nodes = doc.DocumentNode.SelectNodes("//*[@id='list']/div/div/div/div"); 

     // loop through each child 
     if (nodes != null) 
     { 
      foreach (var node in nodes) 
      { 
       Listing listing = new Listing(); 

       // get each individual listing and manually check for nulls 
       // listing.Name = node.SelectSingleNode("./div/div/div/div/h2/a")?.InnerText; --easier way to null check if you can use null propagating operator 
       var nameNode = node.SelectSingleNode("./div/div/div/div/h2/a"); 
       if (nameNode != null) listing.Name = nameNode.InnerText; 

       var addressNode = node.SelectSingleNode("./div/div/div/div/p[@class='result-address']"); 
       if (addressNode != null) listing.Address = addressNode.InnerText.Trim(); 

       var numberNode = node.SelectSingleNode("./div/div/div/div/p[@class='result-number']/a"); 
       if (numberNode != null) listing.Number = numberNode.Attributes["data-visible-number"].Value; 

       result.Add(listing); 
      } 
     } 

     // filter out the nulls 
     result = result.Where(x => x.Name != null && x.Address != null && x.Number != null).ToList(); 

     return result; 
    } 

    public string SerializeTheListings(List<Listing> listings) 
    { 
     var xmlSerializer = new XmlSerializer(typeof(List<Listing>)); 

     using (var stringWriter = new StringWriter()) 
     using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true })) 
     { 
      xmlSerializer.Serialize(xmlWriter, listings); 
      return stringWriter.ToString(); 
     } 
    } 
} 

は、次に、あなたのコードが背後にあるスクレーパーにこのような何か、プラスの参照を見てしまいますクラスおよびモデルクラス:

public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     TheScraper scraper = new TheScraper(); 
     List<Listing> listings = new List<Listing>(); 
     // quick hack to do a loop 5 times, to get all 5 pages. if this is being run frequently you'd want to automatically identify how many pages or start at page one and find/use link to next page. 
     for (int i = 0; i < 5; i++) 
     { 
      listings = listings.Union(scraper.DoTheScrape(i)).ToList(); 
     }    
     string xmlListings = scraper.SerializeTheListings(listings); 
    } 
} 
+0

おかげで非常に多くを、私は重大\tコード\t説明\tプロジェクト\tファイル\tライン\t抑制状態 エラー\t CS8026 \tを得るのですが、 C#5では、 'null propagating operator'機能は使用できません。言語バージョン6以上を使用してください。 \tウェブサイト(2)\t C:\ Users \ g.smith \ valuationapplication \ Gatwick Web Scrape \ website \ gatwickxml.aspx.cs アクティブ –

+0

"?"手動のヌルチェックでは、それはそれが何を指していると思います。 本当に汚い例:node.SelectSingleNode( "./ div/div/div/div/h2/a")!= null? node.SelectSingleNode( "./ div/div/div/div/h2/a")。InnerText:null; –

+0

も参照してください、http://stackoverflow.com/questions/27968963/c-sharp-6-0-features-not-working-with-visual-studio-2015 –

関連する問題