爬取ajax动态渲染页面

scrapy +selenium 爬取ajax动态加载页面

1. 页面样式

  • 有些页面是硬编码在js代码中的。(如豆瓣)
  • 有些页面是使用ajax动态渲染的页面。

2. 问题

  • 动态渲染的页面,在使用scrapy抓取时不能获得与浏览器一模一样的浏览器页面
  • 使用xpath的路径进行解析,并不能获取到相应的元素。

3. 解决方法

  • 调用的ajax的接口,然后解析json,转换成字典。
  • 将获取的页面的body使用进行decode解码,然后使用正则化匹配获取相应的元素。
  • 需要使用的浏览器渲染一波目标页面,然后再将浏览器渲染后的html页面拿给scrapy解析。

4. scrapy+selenium解决方案

  • 首先在settings中打开DOWNLOADER_MIDDLEWARES中间件,将相应的下载中间件打开。
    DOWNLOADER_MIDDLEWARES = {
          
          
       'dataAcquisition.middlewares.DataacquisitionDownloaderMiddleware': 543,
    }
    
  • 修改相应的中间件(DataacquisitionDownloaderMiddleware)中的process_request的方法
    • 使用selenium,将请求的网页的进行动态的渲染,然后将动态渲染完成后的网页进行返回。
    • 注意:使用selenium中的chrome浏览器,首先需要下载chromedriver组件,组件应与chrome的版本相匹配,然后将该组件放到运行环境的bin目录下,如:anaconda环境,应将其放到anaconda环境的Library的bin的目录下面。
    • 使用无页面的浏览器时,需要在前面配置浏览器为无页面的。
      chrome_options = Options()
      chrome_options.add_argument('--headless')
      chrome_options.add_argument('--disable-gpu')
      self.driver = webdriver.Chrome(options=chrome_options)
      
    • 注意,在使用selenium访问相应的页面时,出现跨域访问的bug,这是因为没有添加cookie。可以使用driver.add_cookie来添加cookie。注cookie为直接使用driver.get_cookies()获取的列表中的最后一个。不用修改它的名字之类
    • 使用driver.page_source网页的内容,然后使用scrapy.http.HtmlResponse()进行返回其中body为获取的网页内容,使用encode(‘utf=8’)编码。
    • 注意:一定要使用driver.quit()退出selenium,否则页面不会关闭,造成极大的内存损失。最终导致爬虫系统崩溃。
    • 代码
      chrome_options = Options()
      chrome_options.add_argument('--headless')
      chrome_options.add_argument('--disable-gpu')
      self.driver = webdriver.Chrome(options=chrome_options)
      # print("##middewar数据可以得到吗?e####URL=%s" % request.url)
      cookie =[{
              
              'domain': '.weibo.com', 'expiry': 1618304007.769999, 'httpOnly': False, 'name': 'wvr', 'path': '/', 'secure': False, 'value': '6'},{
              
              'domain': '.weibo.com', 'httpOnly': True, 'name': 'SUB', 'path': '/', 'secure': True, 'value': '_2A25NaFEgDeRhGeBM7VIV9CjEwjmIHXVuHMXorDV8PUNbmtANLWbskW9NRMWPTWP4Gsd_24PQU_NQpBHB6N6mmlnS'}]
      self.driver.add_cookie(cookie_dict=cookie[-1])
      self.driver.get(request.url)
      time.sleep(2)
      # # 获取网页内容
      browser_html = self.driver.page_source
      self.driver.quit()
      # print(browser_html)
      return scrapy.http.HtmlResponse(url=request.url, body=browser_html.encode('utf-8'), encoding='utf-8',request=request)
      

微博的评论内容页面解析

猜你喜欢

转载自blog.csdn.net/weixin_41601540/article/details/115463602