나는 HTML 문서의 모든 링크를 얻고 싶다. 이것은 문제가 아니지만 분명히 모든 링크를 하나씩 배열에 저장하기 전에 알파벳순으로 놓습니다. 나는 원본 순서 (알파벳이 아닌)로 링크를 갖고 싶다.
그래서 첫 번째로 발견 된 링크를 얻고 저장 한 다음 두 번째 링크를 얻을 가능성이 있습니까? HtmlAgilityPack과 Webbrowser-Control 메서드를 사용하여 이미 시도했지만 둘 다 사전 순으로 정렬됩니다. 원래의 순서는 나중에 사용하는 데 중요합니다.
Regex에서 가능할 수도 있다고 들었지만, HTML 파싱에 사용해서는 안되는 충분한 대답을 발견했습니다. 어떻게해야합니까?
다음은 Webbrowser-Control 코드입니다. 링크를 가져 와서 배열에 저장하려고했습니다.
private void btnGet_Click(object sender, EventArgs e)
{
HtmlWindow mainFrame = webFl.Document.Window.Frames["mainFrame"];
HtmlElementCollection links = mainFrame.Document.Links;
foreach (HtmlElement link in links)
{
string linkText = link.OuterHtml;
if (linkText.Contains("puzzle"))
{
arr[i] = linkText;
i++;
}
}
}
미리 감사드립니다, Opak
HTML DOM API를 사용하여 DOM 트리를 이동하여 올바른 순서를 얻을 수 있습니다. 다음 코드는이 작업을 수행합니다. dynamic
API를 사용하여 DOM API에 액세스합니다. WebBrowser
의 HtmlElement.FirstChild
/ HtmlElement.NextSibling
이 DOM 텍스트 노드에 대해 null
을 반환하기 때문에 이러한 목적으로 작동하지 않기 때문입니다.
private void btnGet_Click(object sender, EventArgs e)
{
Action<object> walkTheDom = null;
var links = new List<object>();
// element.FirstChild / NextSibling don't work as they stop at DOM text nodes
walkTheDom = (element) =>
{
dynamic domElement = element;
if (domElement.tagName == "A")
links.Add(domElement);
for (dynamic child = domElement.firstChild; child != null; child = child.nextSibling)
{
if (child.nodeType == 1) // Element node?
walkTheDom(child);
}
};
walkTheDom(this.webBrowser.Document.Body.DomElement);
string html = links.Aggregate(String.Empty, (a, b) => a + ((dynamic)b).outerHtml + Environment.NewLine);
MessageBox.Show(html);
}
[업데이트] dynamic
네이티브 요소 대신 <A>
태그에 대한 HtmlElement
객체 목록을 실제로 얻어야하는 경우 GetElementById
사용하여 약간의 트릭을 사용하여 여전히 가능합니다.
private void btnGet_Click(object sender, EventArgs e)
{
// element.FirstChild / NextSibling don't work because they stop on DOM text nodes
var links = new List<HtmlElement>();
var document = this.webBrowser.Document;
dynamic domDocument = document.DomDocument;
Action<dynamic> walkTheDom = null;
walkTheDom = (domElement) =>
{
if (domElement.tagName == "A")
{
// get HtmlElement for the found <A> tag
string savedId = domElement.id;
string uniqueId = domDocument.uniqueID;
domElement.id = uniqueId;
links.Add(document.GetElementById(uniqueId));
if (savedId != null)
domElement.id = savedId;
else
domElement.removeAttribute("id");
}
for (var child = domElement.firstChild; child != null; child = child.nextSibling)
{
if (child.nodeType == 1) // is an Element node?
walkTheDom(child);
}
};
// walk the DOM for <A> tags
walkTheDom(domDocument.body);
// show the found tags
string combinedHtml = links.Aggregate(String.Empty, (html, element) => html + element.OuterHtml + Environment.NewLine);
MessageBox.Show(combinedHtml);
}