问题:
无法抓取超出选择范围的 html 的问题。单击新链接时,如果涉及 iframe,则很少会将其纳入抓取范围。
解决方案:
选择一种选择新 iframe 的方法,然后继续解析新的 html。
Scrapy-Splash 方法
(这是对this answer的Mikhail Korobov解决方案的改编)
如果你能拿到弹出的新页面的src链接,可能是最靠谱的,不过你也可以试试这样选择iframe:
# ...
yield SplashRequest(url, self.parse_result, endpoint='render.json',
args={'html': 1, 'iframes': 1})
def parse_result(self, response):
iframe_html = response.data['childFrames'][0]['html']
sel = parsel.Selector(iframe_html)
item = {
'my_field': sel.xpath(...),
# ...
}
Selenium 方法
(需要 pip install selenium,bs4,可能还需要从此处为您的操作系统下载 chrome 驱动程序:Selenium Chromedrivers)支持 Javascript 解析!哇哦!
使用以下代码,这会将范围切换到新框架:
# Goes at the top
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.options import Options
import time
# Your path depends on where you downloaded/located your chromedriver.exe
CHROME_PATH = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
CHROMEDRIVER_PATH = 'chromedriver.exe'
WINDOW_SIZE = "1920,1080"
chrome_options = Options()
chrome_options.add_argument("--log-level=3")
chrome_options.add_argument("--headless") # Speeds things up if you don't need gui
chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
chrome_options.binary_location = CHROME_PATH
browser = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=chrome_options)
url = "example_js_site.com" # Your site goes here
browser.get(url)
time.sleep(3) # An unsophisticated way to wait for the new page to load.
browser.switch_to.frame(0)
soup = BeautifulSoup(browser.page_source.encode('utf-8').strip(), 'lxml')
# This will return any content found in tags called '<table>'
table = soup.find_all('table')
这两个选项中我最喜欢的是 Selenium,但如果您对它更满意,请尝试第一个解决方案!