Facebook의 Graph API은 개발자 계정에서 게시물을 작성하지 않는 한 개발자가 허용하지 않으므로 Facebook 그룹의 게시물을 삭제하는 스크립트를 작성하고 있습니다.CasperJS를 사용하여 Facebook 그룹 삭제를 자동화합니다.
지금까지 Facebook에 로그인 한 다음 원하는 그룹 페이지로 이동할 수있었습니다. 거기에서 각 글에 대한 XPath를 페이지에서 볼 수 있습니다 (셀렉터 a[data-testid='post_chevron_button']
사용). 각 XPath 선택기에서 this.click()
을 호출하는 동안 스크립트가 실패합니다. 스크립트가 this.click(x(xpath));
에 도달 할 때
phantom.casperTest = true;
var x = require('casper').selectXPath;
var casper = require('casper').create({
verbose: true,
pageSettings: {
loadImages: false,
loadPlugins: false,
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4'
}
});
// print out all the messages in the headless browser context
casper.on('remote.message', function(msg) {
this.echo('remote message caught: ' + msg);
});
// print out all the messages in the headless browser context
casper.on("page.error", function(msg, trace) {
this.echo("Page Error: " + msg, "ERROR");
});
var url = 'http://www.facebook.com/';
casper.start(url, function() {
console.log("page loaded");
this.test.assertExists('form#login_form', 'form is found');
this.fill('form#login_form', {
email: '{email}',
pass: '{password}'
}, true);
this.click('#u_0_q');
this.wait(1000, function() {
this.echo("Capturing image of page after login.");
this.capture('loggedin.png');
});
});
casper.thenOpen('https://www.facebook.com/groups/{group-id}/', function() {
this.echo(this.getTitle());
this.wait(1000, function() {
this.capture('group.png');
});
var elements = casper.getElementsInfo("a[data-testid='post_chevron_button']");
var index = 1;
elements.forEach(function(element){
var xpath = '//*[@id="' + element.attributes["id"] + '"]';
console.log(xpath);
this.click(x(xpath));
this.wait(100, function() {
this.capture('chevronlink' + index + '.png');
});
index++;
});
});
casper.run();
내가 오류 메시지가
TypeError: undefined is not a constructor (evaluating 'this.click(x(xpath))')
를 얻을 다음과 같이
나의 현재 스크립트입니다. 배열을 생성하는 코드의 마지막 비트를 대체하고 this.click("a[data-testid='post_chevron_button']");
으로 반복하면 스크립트에 문제가 없습니다.
CasperJS가 XPath 선택기로 click()
을 호출하는 것에 대해 싫어하는 점을 알고있는 사람이 있습니까? XPath는 CasperJS의 docs에서 유효한 선택자 인 것으로 보입니다.
UPDATE는
좀 더 정확하게 원하는 결과를 설명하기 위해 질문의 제목을 업데이트했습니다.
당 dasmelch의 조언, 내가 스크립트를 조금 수정 된 대신 스크립트에이 비트를 통합 한 (casper.thenOpen
부분 후) : 지금이 오류가
casper.then(function() {
var elements = casper.getElementsAttribute("a[data-
testid='post_chevron_button']", 'id');
while (elements.length > 0) {
// get always the last element with target id
element = elements.pop();
(function(element) {
var xpath = '//*[@id="' + element + '"]';
console.log(xpath);
// do it step by step
casper.then(function() {
this.click(x(xpath));
});
casper.then(function() {
this.capture('chevronlink' + element + '.png');
});
// go back to the page with the links (if necessary)
casper.then(function() {
casper.back();
});
})(element);
};
});
: Cannot dispatch mousedown event on nonexistent selector: xpath selector: //*[@id="u_0_47"]
.
지난 밤에, 나는 그것에 대해 조금 다르게하기로 결정했습니다. 원하는 최종 결과에 가깝지만 지금은 CasperJS 및/또는 PhantomJS가 post_chevron_button
을 클릭 한 후 드롭 다운에있는 요소를 찾는 데 문제가 있습니다. 여기에 내가 함께 결국 무엇인가 (casper.thenOpen
전에 모든 것을 원래 표시된 스크립트에 동일하게 유지) : (내가 찾고 있어요 값과 ajaxify
속성을 포함하는 요소가 있어야 알고
casper.thenOpen('https://www.facebook.com/groups/{group-id}/', function() {
this.echo(this.getTitle());
this.wait(1000, function() {
this.capture('group.png');
});
var elements = casper.getElementsInfo("a[data-
testid='post_chevron_button']");
while (elements.length > 0) {
this.click("a[data-testid='post_chevron_button']");
this.wait(1000, function() {
this.capture('chevron_click.png');
console.log("chevron_click.png saved");
});
var chevronLinks = casper.getElementsInfo("a[ajaxify]")
console.log("Found " + chevronLinks.length + " elements with ajaxify attribute.");
var chevronLinksIndex = 1;
chevronLinks.forEach(function(element){
var ajaxifyValue = element.attributes["ajaxify"];
console.log(ajaxifyValue);
if (ajaxifyValue.indexOf("delete.php?group_id={group-id}") !== -1) {
this.click("a[ajaxify='"+ajaxifyValue+"']");
this.wait(100, function(){
this.capture('deletePost' + chevronLinksIndex);
});
chevronLinksIndex++;
}
});
if (chevronLinksIndex === 1) {
break;
}
elements = casper.getElementsInfo("a[data-testid='post_chevron_button']");
}
});
브라우저에서 직접 단계별로 실행하면 a[data-testid='post_chevron_button']
을 클릭 한 후에 요소가 표시되지만 캐스퍼는 찾을 수 없기 때문입니다. 뿐만 아니라 내 chevron_click.png
이미지 파일은이 스크립트를 실행할 때마다 업데이트해야하지만 그렇지 않습니다.
일부 코드는 순서대로 실행되지 않습니다. 예를 들어 ajaxify
속성 값의 로깅은 chevron_click.png saved
을보기 전에 콘솔에서 발생합니다. 이것은 예상 할 수 있지만 불행히도 JS 경험이 많지 않습니다. 이 실행 순서 문제는 필요한 요소에 대한 내 검색이 내가 예상 한 것을 반환하지 않는 이유를 설명 할 수 있습니다. 여기
<a class="_54nc" href="#" rel="async-post"
ajaxify="/ajax/groups/mall/delete.php?group_id={group-id}&message_id=806608486110204&story_dom_id=mall_post_806608486110204%3A6%3A0&entstory_context=%7B%22last_view_time%22%3A1495072771%2C%22fbfeed_context%22%3Atrue%2C%22location_type%22%3A2%2C%22outer_object_element_id%22%3A%22mall_post_806608486110204%3A6%3A0%22%2C%22object_element_id%22%3A%22mall_post_806608486110204%3A6%3A0%22%2C%22is_ad_preview%22%3Afalse%2C%22is_editable%22%3Afalse%2C%22mall_how_many_post_comments%22%3A2%2C%22bump_reason%22%3A0%2C%22story_width%22%3A502%2C%22shimparams%22%3A%7B%22page_type%22%3A16%2C%22actor_id%22%3A664025626%2C%22story_id%22%3A806608486110204%2C%22ad_id%22%3A0%2C%22_ft_%22%3A%22%22%2C%22location%22%3A%22group%22%7D%2C%22story_id%22%3A%22u_0_21%22%2C%22caret_id%22%3A%22u_0_22%22%7D&surface=group_post_chevron"
role="menuitem"><span><span class="_54nh"><div class="_41t5"><i
class="_41t7 img sp_gJvT8CoKHU- sx_0f12ae"></i><i class="_41t8 img
sp_s36yWP_7MD_ sx_7e9f7d"></i>Delete Post</div></span></span></a>
불행히도 여전히 같은 오류가 발생합니다. 이 기술은 id 속성을 가져 오는데도 효과적입니다. –
다른 측면에서 테스트 한 결과 효과가있었습니다. console.log (요소)를 사용해 볼 수 있습니까? 나는 그들이 당신의 사건에서 이드를 포함하고 있지 않다고 생각합니다. – dasmelch
각 반복마다 콘솔에 요소를 로깅 중이며 id 값이 올바르게 표시됩니다. 나는 PhantomJS가 함수 호출의 정의를 알지 못할 때 발생하는 에러 메시지를 읽었다. 마치 '캐스퍼 (Casper)'와 같이'forEach' 블록에서 범위를 벗어나는 것과 같은 것입니다. –