Почему мой xpath возвращает обе таблицы, несмотря на указание индекса? - PullRequest
0 голосов
/ 23 апреля 2019

Я использую библиотеку Fuzi Swift для парсинга эта страница хакерских новостей .

Мне нужно извлечь только верхнее описание поста, которое содержит основные детали поста (например, «Возможно, HN»).может помочь решить эту маленькую загадку ......... low.com/a/55711457/2251982)

Прикрепленный скриншот:

enter image description here

Вот мой xpath код:

print("Description: \(String(describing: document.xpath("//*[@id=\"hnmain\"]//tr[2]/td/table[1]//tr[4]/td").first?.rawXML))")

Но мой вывод показывает как таблицы, так и верхнюю запись, а также таблицу комментариев:

Description: Optional("<td>Maybe HN can help solve this little mystery. The default font sizes in HTML have, since at least 1998 [1], been .83em and .67em for h5 and h6, respectively, making them smaller than normal text by default (1em). This leads to the bizarre situation that without any styling, the h5 and h6 headings are smaller than the text they head!<p>Does anyone know why headings were made smaller than normal text? I bet the answer is buried in some mailing list from the mid 90s, but so far my searches have not been fruitful. Perhaps someone here was around at the time of, or was even involved in, this decision.<p>[1] https://stackoverflow.com/a/55711457/2251982</p></p>\n        <tr style=\"height:10px\"/><tr><td colspan=\"2\"/><td>\n          <form method=\"post\" action=\"comment\"><input type=\"hidden\" name=\"parent\" value=\"19722704\"><input type=\"hidden\" name=\"goto\" value=\"item?id=19722704\"><input type=\"hidden\" name=\"hmac\" value=\"78883e7dccb14e8eed04ba1f3b825085ecd4c545\"><textarea name=\"text\" rows=\"6\" cols=\"60\"/>\n                <br><br><input type=\"submit\" value=\"add comment\"/>\n      </br></br>\n  </input><br><br>\n  <table border=\"0\" class=\"comment-tree\">\n            <tr class=\"athing comtr \" id=\"19725000\"><td>\n            <table border=\"0\">  <tr>    <td class=\"ind\"><img src=\"s.gif\" height=\"1\" width=

Почему он выбирает и второй стол?

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

//td/table[1] означает выбор каждого table, который является первым дочерним элементом элемента td, тогда как (//td/table)[1] означает выбор каждого table, который является дочерним элементом элемента td, а затем из всехэти, выберите первый.В частности, оператор x[y] связывается более плотно, чем x/y (или x//y), поэтому x//y[1] означает x//(y[1]), а не (x//y)[1].

0 голосов
/ 24 апреля 2019

Мне удалось решить мою проблему.Оказывается, в библиотеке Fuzi есть ошибки, и ее преобразователь xpath работает неправильно.

Я переключился на библиотеку Kanna, и она прекрасно и точно работает:

https://github.com/tid-kijyun/Kanna

Код моей канны:

let myRequest = NSMutableURLRequest(url: URL(string: "https://news.ycombinator.com/item?id=19722704")!)

let dataTask : URLSessionTask = URLSession.shared.dataTask(with: myRequest as URLRequest, completionHandler: { data, response, error in

    guard error == nil else {
        return
    }

    guard let data = data else {
        return
    }

    if let htmlString = String(bytes: data, encoding: String.Encoding.utf8), let doc = try? HTML(html: htmlString, encoding: .utf8) {

        for postDescription in doc.xpath("//*[@id=\"hnmain\"]//tr[3]/td/table[1]//tr[4]/td[2]") {
            print("postDescription: \(String(describing: postDescription.content))")
        }

        for comment in doc.xpath("//table[@class=\"comment-tree\"]//tr") {
            print("Comment: \(String(describing: comment.content))")
        }
    }

})
dataTask.resume()
...