는 "토크백 메시지"div
가 아닌 #site_comment_74240
<div class="site_comment site_comment-even small normal-rank" id="site_comment_74240">
<div class="talkback-topic">
<a href="/comments/74240?counter=1&num=144" class="show-comment" data-ajax-url="/comments/74240.js?counter=1&num=144">144. מדיניות</a>
</div>
<div class="talkback-username">
<table><tr>
<td>קייזרמן פרדי </td>
<td>(01.11.2013)</td>
</tr></table>
</div>
의 HTML 페이지의 미리보기입니다 HTML 페이지를 처음 가져 오면 오히려 주석 제목을 클릭 할 때 일부 AJAX 쿼리를 통해 비동기 적으로 가져 오므로 각 주석에 대해 가져와야합니다. 문자열로 시작하는 "ID"속성을 가지고, 즉, 모든 div
의 ""site_comment_ "당신은 또한 사용할 수 있습니다
//div[starts-with(@id, "site_comment_"])
:
코멘트 블록, 당신 코드 snipper에 titles
,이 같은 XPath를 사용 잡고 할 수 있습니다 . (내가 XPath를 사용하여 위했던대로) Selector.css()
와 CSS 선택기 귀하의 경우에, 당신은 그래서 중 하나를 사용하여 "ID"접근 방식을 주석 블록을 잡을 수 있습니다
titles = sel.css("div[id^=site_comment_]")
또는없이 "site_comment"클래스를 사용하여 다른 "site_comment-even", "site_comment-odd", "small", "normal-ran"
titles = sel.css("div.site_comment")
그런 다음 당신이 그 의견
div
내부
./div[@class="talkback-topic"]/a[@class="show-comment"]/@data-ajax-url
에서의 URL을 사용하여 새
Request
을 발행 할 것입니다 : 다양 K "또는"높은 순위 ". 또는 CSS 선택자를 사용하여
div.talkback-topic > a.show-comment::attr(data-ajax-url)
(단,
::attr(...)
은 표준이 아니지만 의사 요소 기능을 사용하는 CSS 선택기의 Scrapy 확장 기능)
AJAX 호출에서 얻은 결과는 일부 자바 스크립트 코드이므로 old.after(...)
var old = $("#site_comment_72765");
old.attr('id', old.attr('id') + '_small');
old.hide();
old.after("\n<div class=\"site_comment site_comment-odd large high-rank\" id=\"site_comment_72765\">\n <div class=\"talkback-topic\">\n <a href=\"/comments/72765?counter=42&num=109\" class=\"show-comment\" data-ajax-url=\"/comments/72765.js?counter=42&num=109\">109. ביבי - האדם הנכון בראש ממשלת ישראל(לת)<\/a>\n <\/div>\n \n <div class=\"talkback-message\">\n \n <\/div>\n \n <div class=\"talkback-username\">\n <table><tr>\n <td>ישראל <\/td>\n <td>(11.03.2012)<\/td>\n <\/tr><\/table>\n <\/div>\n <div class=\"rank-controllers\">\n <table><tr>\n \n <td class=\"rabk-link\"><a href=\"#\" data-thumb=\"/comments/72765/thumb?type=up\"><img alt=\"\" src=\"/images/elements/thumbU.png?1376839523\" /><\/a><\/td>\n <td> | <\/td>\n <td class=\"rabk-link\"><a href=\"#\" data-thumb=\"/comments/72765/thumb?type=down\"><img alt=\"\" src=\"/images/elements/thumbD.png?1376839523\" /><\/a><\/td>\n \n <td> | <\/td>\n <td>11<\/td>\n \n <\/tr><\/table>\n <\/div>\n \n <div class=\"talkback-links\">\n <a href=\"/comments/new?add_to_root=true&html_id=site_comment_72765&sibling_id=72765\">תגובה חדשה<\/a>\n \n <a href=\"/comments/72765/comments/new?html_id=site_comment_72765\">הגיבו לתגובה<\/a>\n \n <a href=\"/i/offensive?comment_id=72765\" data-noajax=\"true\">דיווח תוכן פוגעני<\/a>\n <\/div>\n \n<\/div>");
var new_comment = $("#site_comment_72765");
내부의 내용이 당신이 살전로 가야 당신이 해골 거미 뭔가 Selector(text=this_ajax_html_data)
하고 .//div[@class="talkback-message"]//text()
의 XPath 또는 div.talkback-message ::text
CSS 셀렉터 여기
있어 사용하여 다시 분석해야합니다 HTML 데이터입니다 잡아 아이디어 :
from scrapy.spider import BaseSpider
from scrapy.selector import Selector
from scrapy.http import Request
from craigslist_sample.items import CraigslistSampleItem
import urlparse
import re
class MySpider(BaseSpider):
name = "craig"
allowed_domains = ["tbk.co.il"]
start_urls = ["http://www.tbk.co.il/tag/%D7%91%D7%A0%D7%99%D7%9E%D7%99%D7%9F_%D7%A0%D7%AA%D7%A0%D7%99%D7%94%D7%95/talkbacks"]
def parse(self, response):
sel = Selector(response)
comments = sel.css("div.site_comment")
for comment in comments:
item = CraigslistSampleItem()
# this probably has to be fixed
#item["title"] = comment.xpath("div[@class='talkback-message']text()").extract()
# issue an additional request to fetch the Javascript
# data containing the comment text
# and pass the incomplete item via meta dict
for url in comment.css('div.talkback-topic > a.show-comment::attr(data-ajax-url)').extract():
yield Request(url=urlparse.urljoin(response.url, url),
callback=self.parse_javascript_comment,
meta={"item": item})
break
# the line we are looking for begins with "old.after"
# and we want everythin inside the parentheses
_re_comment_html = re.compile(r'^old\.after\((?P<html>.+)\);$')
def parse_javascript_comment(self, response):
item = response.meta["item"]
# loop on Javascript content lines
for line in response.body.split("\n"):
matching = self._re_comment_html.search(line.strip())
if matching:
# what's inside the parentheses is a Javascript strings
# with escaped double-quotes
# a simple way to decode that into a Python string
# is to use eval()
# then there are these "<\/tag>" we want to remove
html = eval(matching.group("html")).replace(r"<\/", "</")
# once we have the HTML snippet, decode it using Selector()
decoded = Selector(text=html, type="html")
# and save the message text in the item
item["message"] = u''.join(decoded.css('div.talkback-message ::text').extract()).strip()
# and return it
return item
scrapy runspider tbkspider.py
을 사용해보세요.
글쎄, 확실히'text()'요소 앞에''div [@ class = 'talkback-message']/text()''라는 슬래시가 없습니다. 그래도이 모든 것이 될지 모르겠다. –
@MarcusRickert에 감사하지만 문제는 "titles"변수에서 미리 시작됩니다 ("scrapy shell"을 사용하여 코드를 디버깅하고 빈 문자열을 반환 함). 그러나 코멘트 주셔서 감사합니다, 당신 말이 맞아요 (나는 당신을 믿는다는 것을 의미합니다. 나는 XPath를 작성하는 방법을 알지 못합니다 ...)). – Cheshie
위에서 언급 한 URL에는 내용이 site_comment site_comment 인 클래스 속성이 없습니다 (심지어 상위 등급이 ""). 다시 확인해 주시겠습니까? 원시 HTML 소스를 보여 주거나'wget' 도구를 사용하여 브라우저를 검색하려면 브라우저의 기능을 사용하십시오. –