Scrapy and Selenium

本文介绍如何利用Scrapy和Selenium配合抓取JavaScript动态生成的网页内容。通过安装配置Selenium并启动Selenium Server,实现对Firefox浏览器的远程控制。文章提供了具体的Python代码示例,展示如何初始化Selenium、打开网页、等待页面加载及获取渲染后的HTML源码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

How to scrapy js?

scrapy结合webkit抓取js生成的页面 http://www.cnblogs.com/Safe3/archive/2011/10/19/2217965.html

rc arch diagram

 

pip install -U selenium

Selenium IDE
http://docs.seleniumhq.org/projects/ide/

Download the server separately, from: http://selenium-release.storage.googleapis.com/2.40/selenium-server-standalone-2.40.0.jar

java -jar selenium-server-standalone-2.40.0.jar

下面我们开始一步步来做:
1. 首先,进入你的电脑上Selenium Server的jar包所在的目录,通过java -jar xxx.jar的方式运行它,程序会自动监听本地的4444端口;
2. 参考我的上一篇博文《如何连入一台没有外网IP的服务器》 ,将本地的4444端口与服务器的4444端口建立Remote映射;
3. 使用Scrapy框架开始编写python程序,具体的例子不再赘述,网上有许多例子,比如这个:https://gist.github.com/1045108。仅描述几个要点:
a) 在python里调用selenium这样写:
self.sel = selenium(“localhost”, 4444, “*firefox”,”http://example.com/”)
不过直接写 “*firefox” 可能会找不到Firefox的路径,这时可以强制指定Firefox的程序路径,比如:”*firefox D:/Program Files/Mozilla Firefox/firefox.exe”。
b) 获取Firefox渲染完成后的HTML代码:

sel = self.selenium
sel.open(response.url)
sel.wait_for_page_to_load(10000)
html = sel.get_eval(“selenium.browserbot.getCurrentWindow().document.getElementsByTagName(‘html’)[0].innerHTML”)

 

from selenium import selenium
from scrapy.spider import BaseSpider
from scrapy.http import Request
import time
import lxml.html
 
class SeleniumSprider(BaseSpider):
    name = "selenium"
    allowed_domains = ['selenium.com']
    start_urls = ["http://localhost"]
    
    def __init__(self,  **kwargs):
        print kwargs
        self.sel = selenium("localhost", 4444, "*firefox","http://selenium.com/")
        self.sel.start()
    
    def parse(self, response):
        sel = self.sel
        sel.open("/index.aspx")
        sel.click("id=radioButton1")
        sel.select("genderOpt", "value=male")
        sel.type("nameTxt", "irfani")
        sel.click("link=Submit")
        time.sleep(1) #wait a second for page to load
        root = lxml.html.fromstring(sel.get_html_source())

 

参考:
http://networkedblogs.com/F9Eph

https://pypi.python.org/pypi/selenium

http://docs.seleniumhq.org/download/

http://yupengyan.com/scrapy-and-selenium.html

### ScrapySelenium 中实现浏览器复用 #### 使用 Selenium 实现浏览器复用 为了提高效率并减少资源消耗,在使用 Selenium 进行网页自动化测试或数据抓取时可以启用浏览器实例的重用。具体方法如下: 通过设置 `options.add_argument("--remote-debugging-port=9222")` 参数来指定调试端口,从而允许外部程序连接到已打开的 Chrome 浏览器实例[^1]。 ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() # 设置远程调试端口号 chrome_options.add_argument('--remote-debugging-port=9222') driver_path = 'path/to/chromedriver' browser = webdriver.Chrome(executable_path=driver_path, options=chrome_options) # 执行操作... ``` 当需要重新利用同一个浏览器窗口而不是每次都创建新的 WebDriver 对象时,可以通过命令行启动带有特定参数的 Chrome 并让后续脚本连入该进程。 对于已经运行中的浏览器,可借助 DevTools Protocol 来建立通信链接,进而控制页面加载行为而不必关闭现有标签页或者整个应用程序。 #### 结合 ScrapySelenium 的方案 Scrapy 是一个强大的异步框架,默认情况下并不支持直接驱动真实浏览器;然而,如果遇到 JavaScript 渲染的内容,则通常会引入中间件如 scrapy-selenium 或者编写自定义下载处理器以集成两者优势。 要使二者协同工作并且能够共享同一浏览器上下文(即所谓的“浏览器复用”),一种常见做法是在初始化阶段仅构建一次 WebDriver 实例,并将其传递给每一个请求处理函数作为附加属性携带下去直到完成全部任务为止。 下面是一个简单的例子展示如何配置这样的环境: ```python import scrapy from selenium import webdriver from selenium.webdriver.chrome.options import Options class MySpider(scrapy.Spider): name = "my_spider" def __init__(self, *args, **kwargs): super(MySpider, self).__init__(*args, **kwargs) chrome_options = Options() chrome_options.add_argument('--remote-debugging-port=9222') # 启动带debug模式的Chrome driver_path = '/usr/local/bin/chromedriver' # chromedriver路径 self.driver = webdriver.Chrome(executable_path=driver_path, options=chrome_options) def parse(self, response): # 利用Selenium进行动态内容解析或其他交互动作 pass closed = lambda spider: getattr(spider, 'driver', None) and spider.driver.quit() # 关闭WebDriver ``` 在这个案例里,每当爬虫开始执行前都会先准备好一个持久化的浏览器对象供内部调用,而在结束之后记得释放相应资源以免造成内存泄漏等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值