간단한 웹 스크레이퍼를 개발하려고합니다. HTML 코드없이 텍스트를 추출하고 싶습니다. 실제로이 목표를 달성했지만 JavaScript 가로 드 된 일부 페이지에서는 좋은 결과를 얻지 못했습니다.
예를 들어, 일부 JavaScript 코드가 텍스트를 추가하면 텍스트를 볼 수 없습니다.
response = urllib2.urlopen(request)
JavaScript가 클라이언트에서 실행되기 때문에 추가 된 텍스트없이 원본 텍스트를 얻습니다.
그래서이 문제를 해결할 아이디어를 찾고 있습니다.
답변
2017 년 12 월 30 일 수정 :이 답변은 Google 검색의 최상위 결과에 표시되므로 업데이트하기로 결정했습니다. 오래된 대답은 여전히 끝났습니다.
dryscape는 더 이상 유지되지 않으며 라이브러리 dryscape 개발자는 Python 2 만 권장합니다. 나는 Phantom JS와 함께 Selenium의 python 라이브러리를 웹 드라이버로 사용하여 빠르고 쉽게 작업을 수행하는 것을 발견했습니다.
Phantom JS를 설치했으면 phantomjs
바이너리가 현재 경로에서 사용 가능한지 확인하십시오 .
phantomjs --version
# result:
2.1.1
예
예를 들어, 다음 HTML 코드로 샘플 페이지를 작성했습니다. ( 링크 ) :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Javascript scraping test</title>
</head>
<body>
<p id='intro-text'>No javascript support</p>
<script>
document.getElementById('intro-text').innerHTML = 'Yay! Supports javascript';
</script>
</body>
</html>
자바 스크립트가 없으면 다음 No javascript support
과 같이 나타납니다.Yay! Supports javascript
JS 지원이없는 스크래핑 :
import requests
from bs4 import BeautifulSoup
response = requests.get(my_url)
soup = BeautifulSoup(response.text)
soup.find(id="intro-text")
# Result:
<p id="intro-text">No javascript support</p>
JS 지원으로 스크래핑 :
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get(my_url)
p_element = driver.find_element_by_id(id_='intro-text')
print(p_element.text)
# result:
'Yay! Supports javascript'
Python 라이브러리 dryscrape 를 사용 하여 Javascript 기반 웹 사이트를 긁을 수도 있습니다 .
JS 지원으로 스크래핑 :
import dryscrape
from bs4 import BeautifulSoup
session = dryscrape.Session()
session.visit(my_url)
response = session.body()
soup = BeautifulSoup(response)
soup.find(id="intro-text")
# Result:
<p id="intro-text">Yay! Supports javascript</p>
답변
자바 스크립트로 생성 된 콘텐츠를 DOM에서 렌더링해야하므로 올바른 결과를 얻지 못했습니다. HTML 페이지를 가져올 때 자바 스크립트 DOM에 의해 수정되지 않은 초기를 가져옵니다.
따라서 페이지를 크롤링하기 전에 자바 스크립트 컨텐츠를 렌더링해야합니다.
이 스레드에서 셀레늄이 이미 여러 번 언급되었으므로 (그리고 때때로 느리게 진행되는 경우도 언급되었으므로) 가능한 두 가지 다른 솔루션을 나열합니다.
해결 방법 1 : 이것은 Scrapy를 사용하여 자바 스크립트로 생성 된 콘텐츠를 크롤링하는 방법 에 대한 매우 유용한 자습서 입니다.
우리가 필요한 것 :
-
기계에 Docker가 설치되었습니다. 이것은 OS 독립적 인 플랫폼을 사용하므로이 시점까지 다른 솔루션에 비해 장점입니다.
-
해당 OS에 대해 나열된 지침에 따라 Splash를 설치 하십시오.
스플래시 문서에서 인용 :Splash는 자바 스크립트 렌더링 서비스입니다. Twisted 및 QT5를 사용하여 Python 3에서 구현 된 HTTP API를 갖춘 경량 웹 브라우저입니다.
기본적으로 Splash를 사용하여 Javascript로 생성 된 컨텐츠를 렌더링합니다.
-
스플래시 서버를 실행하십시오
sudo docker run -p 8050:8050 scrapinghub/splash
.. -
scrapy-splash 플러그인을 설치하십시오 :
pip install scrapy-splash
-
우리는 이미 (, 아니라면 만든 Scrapy 프로젝트가 있다고 가정 의 메이크업 하나하자 , 우리는 가이드를 따라 업데이트됩니다)
settings.py
:그런 다음 귀찮은 프로젝트로 이동하여
settings.py
다음 미들웨어를 설정하십시오.DOWNLOADER_MIDDLEWARES = { 'scrapy_splash.SplashCookiesMiddleware': 723, 'scrapy_splash.SplashMiddleware': 725, 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810, }
Splash 서버의 URL (Win 또는 OSX를 사용하는 경우 도커 시스템의 URL이어야합니다 . 호스트에서 Docker 컨테이너의 IP 주소를 얻는 방법은 무엇입니까? ) :
SPLASH_URL = 'http://localhost:8050'
마지막으로 다음 값도 설정해야합니다.
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter' HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
-
마지막으로 다음을 사용할 수 있습니다
SplashRequest
.일반 스파이더에는 URL을 여는 데 사용할 수있는 Request 객체가 있습니다. 열려는 페이지에 JS 생성 데이터가 포함되어 있으면 SplashRequest (또는 SplashFormRequest)를 사용하여 페이지를 렌더링해야합니다. 다음은 간단한 예입니다.
class MySpider(scrapy.Spider): name = "jsscraper" start_urls = ["http://quotes.toscrape.com/js/"] def start_requests(self): for url in self.start_urls: yield SplashRequest( url=url, callback=self.parse, endpoint='render.html' ) def parse(self, response): for q in response.css("div.quote"): quote = QuoteItem() quote["author"] = q.css(".author::text").extract_first() quote["quote"] = q.css(".text::text").extract_first() yield quote
SplashRequest는 URL을 html로 렌더링하고 callback (parse) 메서드에서 사용할 수있는 응답을 반환합니다.
해결 방법 2 : 이 실험을 지금 바로 호출 해 봅시다 (2018 년 5 월) …
이 솔루션은 현재 Python 버전 3.6 에만 해당됩니다.
요청 모듈 을 알고 있습니까?
이제 웹 크롤링 작은 형제가 있습니다 : requests-HTML :
이 라이브러리는 HTML 구문 분석 (예 : 웹 스크랩)을 가능한 한 간단하고 직관적으로 만듭니다.
-
설치 요청 -html :
pipenv install requests-html
-
페이지 URL을 요청하십시오.
from requests_html import HTMLSession session = HTMLSession() r = session.get(a_page_url)
-
Javascript 생성 비트를 얻기 위해 응답을 렌더링하십시오.
r.html.render()
마지막 으로이 모듈은 스크래핑 기능 을 제공하는 것으로 보입니다 .
또는 방금 렌더링 한 객체 와 함께 BeautifulSoup 을 잘 문서화 한 방법으로 시도 할 수 있습니다 r.html
.
답변
아마도 셀레늄 이 그것을 할 수 있습니다.
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get(url)
time.sleep(5)
htmlSource = driver.page_source
답변
Requests
이전에 파이썬 에서 모듈을 사용한 적이 있다면 최근에 개발자 Requests-HTML
가 JavaScript를 렌더링 할 수 있는 새로운 모듈을 만들었습니다 .
https://html.python-requests.org/ 를 방문 하여이 모듈에 대해 자세히 알아 보거나 JavaScript 렌더링에 관심이있는 경우 https://html.python-requests.org/?#javascript 를 방문 하십시오. -지원 모듈을 사용하여 Python을 사용하여 JavaScript를 렌더링하는 방법을 직접 학습합니다.
기본적으로 Requests-HTML
모듈 을 올바르게 설치하면 위의 링크에 표시된 다음 예제는 이 모듈을 사용하여 웹 사이트를 긁어 내고 웹 사이트에 포함 된 JavaScript를 렌더링하는 방법을 보여줍니다.
from requests_html import HTMLSession
session = HTMLSession()
r = session.get('http://python-requests.org/')
r.html.render()
r.html.search('Python 2 will retire in only {months} months!')['months']
'<time>25</time>' #This is the result.
최근 YouTube 동영상에서 이에 대해 배웠습니다. 여기를 클릭하십시오! 모듈 작동 방식을 보여주는 YouTube 동영상을 시청합니다.
답변
이것은 훌륭한 블로그 게시물 에서 가져온 좋은 솔루션 인 것 같습니다.
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *
from lxml import html
#Take this class for granted.Just use result of rendering.
class Render(QWebPage):
def __init__(self, url):
self.app = QApplication(sys.argv)
QWebPage.__init__(self)
self.loadFinished.connect(self._loadFinished)
self.mainFrame().load(QUrl(url))
self.app.exec_()
def _loadFinished(self, result):
self.frame = self.mainFrame()
self.app.quit()
url = 'http://pycoders.com/archive/'
r = Render(url)
result = r.frame.toHtml()
# This step is important.Converting QString to Ascii for lxml to process
# The following returns an lxml element tree
archive_links = html.fromstring(str(result.toAscii()))
print archive_links
# The following returns an array containing the URLs
raw_links = archive_links.xpath('//div[@class="campaign"]/a/@href')
print raw_links
답변
실제로 찾고있는 데이터는 기본 페이지의 일부 자바 스크립트에서 호출 한 보조 URL을 통해 액세스 할 수있는 것처럼 들립니다.
서버에서 자바 스크립트를 실행하여이 문제를 처리 할 수는 있지만 Firefox를 사용하여 페이지를로드하고 Charles 또는 Firebug 와 같은 도구를 사용하여 해당 보조 URL이 무엇인지 정확히 식별 하는 간단한 방법이 있습니다 . 그런 다음 관심있는 데이터에 대해 해당 URL을 직접 쿼리하면됩니다.
답변
Selenium은 JS 및 Ajax 컨텐츠를 스크랩하는 데 가장 적합합니다.
Python을 사용하여 웹에서 데이터 를 추출하려면 이 기사를 확인하십시오.
$ pip install selenium
그런 다음 Chrome 웹 드라이버를 다운로드하십시오.
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("https://www.python.org/")
nav = browser.find_element_by_id("mainnav")
print(nav.text)
쉬운가요?