클래스 또는 ID가없는 제품 페이지에서 정보를 수집해야합니다. htmlagilitypack 및 C # 4.0 사용하고 있습니다.
이 제품 페이지 소스 코드에는 많은 테이블이 있습니다. 가격 테이블에는 "KDV"문자열이 포함됩니다. 그래서이 "KDV"문자열을 포함하는 문자열을 얻고 싶습니다. 내가 어떻게 할 수 있니?
아래의 xpath는 예를 들어 모든 테이블을 선택합니다.
string srxPathOfCategory = "//table";
var selectedNodes = myDoc.DocumentNode.SelectNodes(srxPathOfCategory);
아래 코드는 테이블을 선택하지만 가장 바깥 쪽 테이블부터 시작합니다. 주어진 문자열을 포함하는 대부분의 내부 테이블을 선택해야합니다.
//table[contains(., ' KDV')]
C #, xpath, htmlagilitypack
아래 코드는 테이블을 선택하지만 가장 바깥 쪽 테이블부터 시작합니다. 주어진 문자열을 포함하는 대부분의 내부 테이블을 선택해야합니다.
사용 :
//table
[not(descendant::table)
and
.//text()[contains(., ' KDV')]
]
그러면 XML 자에서 table
하위 항목이없고 " KDV"
. 자열을 포함하는 텍스트 노드 자손이있는 table
이 선택됩니다.
일반적으로 위의 표현식은 많은 table
요소를 선택할 수 있습니다.
이 중 하나만 선택하면 (첫 번째 말하기)이 XPath 표현식을 사용하십시오. 대괄호에주의하십시오 .
(//table
[not(descendant::table)
and
.//text()[contains(., ' KDV')]
]
)[1]
기억하십시오 : 문서에서 첫 번째 someName
요소를 선택하려면 다음을 사용합니다 (현재 허용 된 답변 에서처럼).
//someName[1]
이것은 XPath에서 두 번째로 많이 쓰이는 FAQ입니다 (기본 네임 스페이스가있는 XML 문서에서 접두어가없는 이름을 가진 요소를 선택하는 방법을 따랐습니다).
위의 표현식은 실제로 문서의 someName
요소, 즉 부모의 첫 번째 자식을 선택합니다.
이 비 직관적 인 동작의 이유는 XPath []
연산자가 //
의사 연산자보다 우선 순위가 높기 때문입니다.
존재하는 경우 (XML 문서의) 첫 번째 someName
요소 만 실제로 선택하는 올바른 표현식은 다음과 같습니다.
(//someName)[1]
여기서 대괄호는 기본 XPath 연산자 우선 순위를 명시 적으로 무시하는 데 사용됩니다.
더 효율적인 방법이있을 수 있습니다. 어쨌든, 이것은 내가 당신의 경우에 사용했던 전체 코드이며 그것은 나를 위해 작동합니다 :
HtmlDocument doc = new HtmlDocument();
string url = "http://www.pratikev.com/fractalv33/pratikEv/pages/viewProduct.jsp?pInstanceId=3138821";
using (var response = (WebRequest.Create(url).GetResponse()))
{
doc.LoadHtml(new StreamReader(response.GetResponseStream()).ReadToEnd());
}
/*There is an bug in the xpath used here. Should have been
(//table/tr/td/font[contains(.,'KDV')])[1]/ancestor::table[2]
See Dimitre's answer for an explanation and an alternative /
more generic / (needless to say) better approach */
string xpath = "//table/tr/td/font[contains(.,'KDV')][1]/ancestor::table[2]";
HtmlNode table = doc.DocumentNode.SelectSingleNode(xpath);