스크래피를 사용하여 AJAX를 사용하는 웹사이트에서 동적 콘텐츠를 스크래치할 수 있습니까?
나는 최근에 파이썬을 배우고 있고 웹 스크레이퍼를 만드는 일에 몰두하고 있다.그것은 전혀 화려하지 않다; 그것의 목적은 베팅 웹사이트에서 데이터를 가져와 엑셀에 넣는 것이다.
대부분의 문제들은 해결할 수 있고 나는 아주 작은 혼란을 겪고 있다.하지만 나는 한 가지 이슈에 대해 엄청난 장애물을 부딪치고 있다.사이트에서 말의 표를 로드하고 현재 베팅 가격을 나열하는 경우 이 정보는 소스 파일에 없습니다.단서는 이 데이터가 라이브인 경우가 있다는 것입니다.이 데이터는 분명히 리모트서버로부터 갱신되고 있습니다.제 PC의 HTML에는 단순히 서버가 제가 필요로 하는 모든 흥미로운 데이터를 처리하는 구멍이 있습니다.
동적 웹 콘텐츠에 대한 경험이 부족하기 때문에 이 문제를 이해하는 데 어려움을 겪고 있습니다.
자바나 Javascript가 핵심인 것 같은데, 이런게 자주 뜬다.
스크레이퍼는 단순히 승산 비교 엔진입니다.API가 있는 사이트도 있지만 없는 사이트에는 이것이 필요합니다.Python 2.7과 함께 스크래치 라이브러리를 사용하고 있습니다.
이 질문이 너무 자유롭다면 사과드립니다.즉, 어떻게 스크래피를 사용하여 이 동적 데이터를 스크래치하여 사용할 수 있는가 하는 것입니다.내가 실시간으로 이 베팅 확률 데이터를 긁어모을 수 있도록?
.scrapy
AJAX 요구로 설정합니다.사이트 rubin-kazan.ru 를 참조해 주세요.
모든 메시지에 AJAX 요청이 로드됩니다.이 메시지를 모든 속성(작성자, 날짜 등)과 함께 가져오는 것이 목표입니다.
페이지의 소스 코드를 분석하면 웹 페이지가 AJAX 기술을 사용하기 때문에 이러한 모든 메시지를 볼 수 없습니다.그러나 Mozilla Firefox의 Firebug(또는 다른 브라우저의 동등한 도구)를 사용하여 웹 페이지에서 메시지를 생성하는 HTTP 요청을 분석할 수 있습니다.
전체 페이지를 새로고침하지 않고 메시지가 포함된 페이지 부분만 새로고침합니다.이를 위해 아래쪽에 있는 임의의 페이지 수를 클릭합니다.
메시지 본문을 담당하는 HTTP 요구를 확인합니다.
완료 후 요청 헤더를 분석합니다(var 섹션에서 소스 페이지에서 추출하는 이 URL을 인용해야 합니다. 아래 코드를 참조하십시오).
또한 요청의 양식 데이터 내용(HTTP 메서드는 "Post"):
응답 내용은 JSON 파일입니다.
내가 찾고 있는 모든 정보를 보여주는 거죠
지금부터 나는 이 모든 지식을 스크래피로 구현해야 한다.이 목적을 위해 거미를 정의합니다.
class spider(BaseSpider):
name = 'RubiGuesst'
start_urls = ['http://www.rubin-kazan.ru/guestbook.html']
def parse(self, response):
url_list_gb_messages = re.search(r'url_list_gb_messages="(.*)"', response.body).group(1)
yield FormRequest('http://www.rubin-kazan.ru' + url_list_gb_messages, callback=self.RubiGuessItem,
formdata={'page': str(page + 1), 'uid': ''})
def RubiGuessItem(self, response):
json_file = response.body
»parse
기능하다 »RubiGuessItem
JSON을 사용하다
Google Chrome Safari (Google Chrome ) 。에서는 Chrome을 열 수.Menu->Tools->Developer Tools
. 。Network
탭에서는 모든 요청 및 응답에 대한 모든 정보를 볼 수 있습니다.
으로 이동시켜 놓은 을 볼 수 XHR
code. script code 의의 의 made made made made made made made made 。
힌트: 페이지를 로드할 때마다 로그가 지워집니다.사진 하단의 검은 점 버튼으로 로그가 유지됩니다.
요청 및 응답을 분석한 후 웹 크롤러에서 이러한 요청을 시뮬레이션하고 중요한 데이터를 추출할 수 있습니다.대부분의 경우 HTML을 해석하는 것보다 데이터를 얻는 것이 더 쉬울 것입니다.왜냐하면 HTML 데이터는 프레젠테이션 로직을 포함하지 않고 Javascript 코드로 접근하도록 포맷되어 있기 때문입니다.
파이어폭스는 파이어버그라고 불리는 비슷한 확장자를 가지고 있다.어떤 사람들은 파이어버그가 더 강력하다고 주장하겠지만 나는 웹킷의 단순성이 좋다.
크롤링할 때 페이지에 렌더링된 콘텐츠가 Javascript로 생성되어 스크래피가 크롤링할 수 없는 문제가 자주 발생합니다(예: ajax requests, jQuery crazy).
그러나 웹 테스트 프레임워크 Selenium과 함께 Scrapy를 사용하면 일반 웹 브라우저에 표시되는 모든 항목을 크롤링할 수 있습니다.
주의사항:
Python 버전의 Selenium RC가 설치되어 있고 Selenium이 올바르게 설정되어 있어야 합니다.그리고 이건 그냥 템플릿 크롤러에요.당신은 더 미쳐가고 더 발전될 수 있지만 나는 단지 기본적인 아이디어를 보여주고 싶었다.현재 코드 상태에서는 임의의 URL에 대해 2개의 요청을 수행합니다.하나는 Scrapy에 의해 요청되고 다른 하나는 Selenium에 의해 요청됩니다.Selenium에게 유일한 요청을 할 수 있는 방법이 있을 것입니다만, 저는 그것을 굳이 실시하지 않았고, 2개의 요청을 하면 Scrapy도 페이지를 탐색할 수 있습니다.
렌더링된 전체 DOM을 크롤링할 수 있고 Scrapy의 모든 멋진 크롤링 기능을 사용할 수 있기 때문에 이 기능은 매우 강력합니다.이것에 의해, 물론 천천히 기어가지만, 렌더링된 DOM 의 필요량에 따라서는, 기다릴 필요가 있습니다.
from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor from scrapy.selector import HtmlXPathSelector from scrapy.http import Request from selenium import selenium class SeleniumSpider(CrawlSpider): name = "SeleniumSpider" start_urls = ["http://www.domain.com"] rules = ( Rule(SgmlLinkExtractor(allow=('\.html', )), callback='parse_page',follow=True), ) def __init__(self): CrawlSpider.__init__(self) self.verificationErrors = [] self.selenium = selenium("localhost", 4444, "*chrome", "http://www.domain.com") self.selenium.start() def __del__(self): self.selenium.stop() print self.verificationErrors CrawlSpider.__del__(self) def parse_page(self, response): item = Item() hxs = HtmlXPathSelector(response) #Do some XPath selection with Scrapy hxs.select('//div').extract() sel = self.selenium sel.open(response.url) #Wait for javscript to load in Selenium time.sleep(2.5) #Do some crawling of javascript created content with Selenium sel.get_text("//div") yield item # Snippet imported from snippets.scrapy.org (which no longer works) # author: wynbennett # date : Jun 21, 2011
참고 자료: http://snipplr.com/view/66998/
또 다른 해결책은 다운로드 핸들러를 구현하거나 핸들러 미들웨어를 다운로드하는 것입니다.(다운로더 미들웨어에 대한 자세한 내용은 스크래치 문서를 참조하십시오.)다음은 헤드리스 phantomjs 웹 드라이버와 함께 셀레늄을 사용한 클래스 예입니다.
1) 클래스 정의middlewares.py
★★★★★★ 。
from selenium import webdriver
from scrapy.http import HtmlResponse
class JsDownload(object):
@check_spider_middleware
def process_request(self, request, spider):
driver = webdriver.PhantomJS(executable_path='D:\phantomjs.exe')
driver.get(request.url)
return HtmlResponse(request.url, encoding='utf-8', body=driver.page_source.encode('utf-8'))
2) 추가JsDownload()
variable class class classDOWNLOADER_MIDDLEWARE
의 범위 내에서settings.py
:
DOWNLOADER_MIDDLEWARES = {'MyProj.middleware.MiddleWareModule.MiddleWareClass': 500}
3) 통합HTMLResponse
의 범위 내에서your_spider.py
을 디코딩하면 얻을 수 응답 본문을 디코딩하면 원하는 출력을 얻을 수 있습니다.
class Spider(CrawlSpider):
# define unique name of spider
name = "spider"
start_urls = ["https://www.url.de"]
def parse(self, response):
# initialize items
item = CrawlerItem()
# store data as items
item["js_enabled"] = response.body.decode("utf-8")
「이것들」은 다음과 같습니다.
저는 어떤 미들웨어를 사용해야 하는지 다른 거미들에게 알려주는 기능을 원했기 때문에 이 래퍼를 구현했습니다.
def check_spider_middleware(method):
@functools.wraps(method)
def wrapper(self, request, spider):
msg = '%%s %s middleware step' % (self.__class__.__name__,)
if self.__class__ in spider.middleware:
spider.log(msg % 'executing', level=log.DEBUG)
return method(self, request, spider)
else:
spider.log(msg % 'skipping', level=log.DEBUG)
return None
return wrapper
래퍼가 작동하려면 모든 거미들이 최소한 다음을 가지고 있어야 합니다.
middleware = set([])
미들웨어 포함:
middleware = set([MyProj.middleware.ModuleName.ClassName])
★★★★
스파이더보다 이 방법으로 실행하는 것의 가장 큰 장점은 결국 하나의 요청만 하게 된다는 것입니다.T자, T자, T자, T자, T자, T자, T자, T자.다운로드 핸들러는 요청을 처리하고 스파이더에게 응답을 전달합니다.parse_page parse_page parse_page parse_page parse_page parse_page parse_page parse_page 。이것은 같은 콘텐츠에 대한 두 가지 요청입니다.
커스텀 다운로더 미들웨어를 사용하고 있었지만 캐시를 사용할 수 없었기 때문에 그다지 만족하지 못했습니다.
더 나은 방법은 커스텀 다운로드 핸들러를 구현하는 것입니다.
여기 작업 예가 있습니다.다음과 같습니다.
# encoding: utf-8
from __future__ import unicode_literals
from scrapy import signals
from scrapy.signalmanager import SignalManager
from scrapy.responsetypes import responsetypes
from scrapy.xlib.pydispatch import dispatcher
from selenium import webdriver
from six.moves import queue
from twisted.internet import defer, threads
from twisted.python.failure import Failure
class PhantomJSDownloadHandler(object):
def __init__(self, settings):
self.options = settings.get('PHANTOMJS_OPTIONS', {})
max_run = settings.get('PHANTOMJS_MAXRUN', 10)
self.sem = defer.DeferredSemaphore(max_run)
self.queue = queue.LifoQueue(max_run)
SignalManager(dispatcher.Any).connect(self._close, signal=signals.spider_closed)
def download_request(self, request, spider):
"""use semaphore to guard a phantomjs pool"""
return self.sem.run(self._wait_request, request, spider)
def _wait_request(self, request, spider):
try:
driver = self.queue.get_nowait()
except queue.Empty:
driver = webdriver.PhantomJS(**self.options)
driver.get(request.url)
# ghostdriver won't response when switch window until page is loaded
dfd = threads.deferToThread(lambda: driver.switch_to.window(driver.current_window_handle))
dfd.addCallback(self._response, driver, spider)
return dfd
def _response(self, _, driver, spider):
body = driver.execute_script("return document.documentElement.innerHTML")
if body.startswith("<head></head>"): # cannot access response header in Selenium
body = driver.execute_script("return document.documentElement.textContent")
url = driver.current_url
respcls = responsetypes.from_args(url=url, body=body[:100].encode('utf8'))
resp = respcls(url=url, body=body, encoding="utf-8")
response_failed = getattr(spider, "response_failed", None)
if response_failed and callable(response_failed) and response_failed(resp, driver):
driver.close()
return defer.fail(Failure())
else:
self.queue.put(driver)
return defer.succeed(resp)
def _close(self):
while not self.queue.empty():
driver = self.queue.get_nowait()
driver.close()
스크레이퍼를 "scraper"라고 합니다.언급한 코드를 "handlers.py" 폴더의 루트에 있는 파일 안에 넣으면 설정에 추가할 수 있습니다.py:
DOWNLOAD_HANDLERS = {
'http': 'scraper.handlers.PhantomJSDownloadHandler',
'https': 'scraper.handlers.PhantomJSDownloadHandler',
}
또한 JS는 DOM을 스크래피 캐시, 리트라이 등으로 해석했습니다.
스크래피를 사용하여 이 동적 데이터를 스크래핑하여 사용할 수 있습니까?
왜 Scrapy만을 사용하여 솔루션을 게시하지 않았는지 궁금합니다.
Scrapy team Scraping INFINITE SCroll PAGES의 블로그 투고를 확인해 주세요.이 예에서는 무한 스크롤을 사용하는 http://spidyquotes.herokuapp.com/scroll 웹사이트를 스크랩하고 있습니다.
브라우저의 Developer Tools를 사용하여 AJAX 요청을 확인한 후 이 정보를 기반으로 Scrapy 요청을 작성합니다.
import json
import scrapy
class SpidyQuotesSpider(scrapy.Spider):
name = 'spidyquotes'
quotes_base_url = 'http://spidyquotes.herokuapp.com/api/quotes?page=%s'
start_urls = [quotes_base_url % 1]
download_delay = 1.5
def parse(self, response):
data = json.loads(response.body)
for item in data.get('quotes', []):
yield {
'text': item.get('text'),
'author': item.get('author', {}).get('name'),
'tags': item.get('tags'),
}
if data['has_next']:
next_page = data['page'] + 1
yield scrapy.Request(self.quotes_base_url % next_page)
API인 외부 URL에서 생성된 데이터는 POST 메서드로 HTML 응답을 호출합니다.
import scrapy
from scrapy.crawler import CrawlerProcess
class TestSpider(scrapy.Spider):
name = 'test'
def start_requests(self):
url = 'https://howlongtobeat.com/search_results?page=1'
payload = "queryString=&t=games&sorthead=popular&sortd=0&plat=&length_type=main&length_min=&length_max=&v=&f=&g=&detail=&randomize=0"
headers = {
"content-type":"application/x-www-form-urlencoded",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36"
}
yield scrapy.Request(url,method='POST', body=payload,headers=headers,callback=self.parse)
def parse(self, response):
cards = response.css('div[class="search_list_details"]')
for card in cards:
game_name = card.css('a[class=text_white]::attr(title)').get()
yield {
"game_name":game_name
}
if __name__ == "__main__":
process =CrawlerProcess()
process.crawl(TestSpider)
process.start()
2022년에 언급해야 할 현대적 대안이 몇 가지 더 있는데, 이 질문에 대한 보다 대중적인 답변에서 논의된 방법에 대해 몇 가지 장단점을 나열하고 싶습니다.
과 그 의 몇 에 대해 합니다.
dev tools
하여 응답 합니다.url
한 번 바랍니다.scrapy.Request
s.이이며, 한 경우 보다 더 할 수 있습니다를 들어 HTML에서 할 수 있습니다: 에 : 이 、 에 、 에 、 에 、 에에에HTML pros pros pros pros pros pros pros pros pros pros pros pros pros pros pros i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 。
xpath
★★★★★★★★★★★★★★★★★」css
셀렉터단점: 유감스럽게도 이것은 극히 일부 동적 사이트에서만 이용할 수 있으며, 많은 경우 웹 사이트에서는 이 전략을 사용하는 것을 어렵게 하는 보안 조치를 시행하고 있습니다.
「」를 사용합니다.
Selenium Webdriver
앞의 답변에서 많이 언급되었던 다른 접근법입니다.장점: 구현이 용이하고 쓰레기가 많은 워크플로우에 통합이 용이합니다. 많은 , 「」등의 를 사용하는 는, 없습니다.
scrapy-selenium
단점: 느리다!스크래피의 주요 기능 중 하나는 비동기 워크플로우를 통해 수십 또는 수백 페이지를 몇 초 만에 쉽게 크롤링할 수 있다는 것입니다.셀레늄을 사용하면 이것을 상당히 줄일 수 있다.
가 있는 두 .scrapy-splash
★★★★★★★★★★★★★★★★★」scrapy-playwright
.
긁힘 방지:
- 스크래피 워크플로우에 스크래피 개발자가 만들고 유지 관리하는 자바스크립트 렌더링 서비스인 스플래시를 통합하는 스크래피 플러그인입니다.플러그인은 pypi에서 설치할 수 있습니다.
pip3 install scrapy-splash
자체
스크래피 극작가:
- 는 Playwright와 같은 입니다.
selenium
하지만 셀레늄 사용으로 인한 속도 저하를 막지는 못합니다.Playwrite는 비동기 스크래피 워크플로우에 적합하여 스크래피만 사용하는 것처럼 요청을 빠르게 전송할 수 있습니다.또한 셀레늄보다 설치 및 통합이 훨씬 쉽습니다.scrapy-playwright
되며, 러인 py py py py py py py py py py py py py py py py py py py, pypi를를 plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin plugin,pip3 install scrapy-playwright
가playwright install
터미널에 있습니다.
상세한 것에 대하여는, 플러그 인의 각 github 페이지(https://github.com/scrapy-plugins/scrapy-splash 와 https://github.com/scrapy-plugins/scrapy-splash 를 참조해 주세요.
p.s. 제 경험상 두 프로젝트 모두 Linux 환경에서 더 잘 작동하는 경향이 있습니다.Windows 사용자의 경우 Windows Subsystem for Linux(wsl)와 함께 사용할 것을 권장합니다.
네, Scrapy는 JavaScript를 통해 렌더링되는 동적 웹 사이트, 즉 웹 사이트를 스크래핑할 수 있습니다.
이런 종류의 웹사이트들을 스크래핑하는 데는 두 가지 방법이 있다.
하면 .
splash
Javascript 코드를 렌더링하고 렌더링된 HTML을 구문 분석하려면 여기서 문서와 프로젝트를 찾을 수 있습니다. Scrapy splash, git설명한 바와 같이 '감시'를
network calls
수 콜을 스파이더로 할 수 있습니다.그리고 그 호출을 당신의 쓰레기가 많은 거미로 조롱하면 원하는 데이터를 얻을 수 있습니다.
Selenium과 Firefox 웹 드라이버를 사용하여 Ajax 요청을 처리합니다.크롤러가 데몬으로 필요한 경우에는 그리 빠르지 않지만 수동 솔루션보다 훨씬 좋습니다.
언급URL : https://stackoverflow.com/questions/8550114/can-scrapy-be-used-to-scrape-dynamic-content-from-websites-that-are-using-ajax
'programing' 카테고리의 다른 글
TypeScript React에서 이미지 Import - "모듈을 찾을 수 없습니다" (0) | 2023.03.06 |
---|---|
타임아웃 Feign Client 해결 방법 (0) | 2023.03.06 |
이 FB는 뭐야?Native Extensions.onready 콘솔 오류는 Facebook과 관련되어 있으며 어떻게 해결할 수 있습니까? (0) | 2023.03.06 |
ui-ipsec 상태 변경에서 $state.current.name를 반환하려면 어떻게 해야 합니까? (0) | 2023.03.01 |
Jquery Ajax를 사용하여 Mysql에서 데이터 검색 (0) | 2023.03.01 |