python爬虫加载动态网页的几种方式,selenium,splinter,Scrapy Splash,PhantomJS,Chrome,Firefox

部分网站是动态js加载,加载网页后无法找到实际抓取内容。如今日头条等,反爬比较厉害,api不好破解的情况下只能通过浏览器模拟渲染加载方式,不过selenium等驱动浏览器很有一定标识和指纹,很容易被识别。selenium浏览器driver 源码中某个变量名是表示该驱动特征的,变量名会被识别,一般办法是改变变量名称或者拦截包含该变量名的请求就行了,拦截需要中间件。由于修改太繁琐,网上也有编译好的Chromedriver,特征已经被抹除,这样就不会被今日头条,知乎识别到。暂时发现Scrapy Splash识别不到,可以正常加载爬取。

 

1.可以基于selenium webdriver,Chrome,Firefox, PhantomJS无界面浏览器加载。selenium中文文档: https://python-selenium-zh.readthedocs.io/zh_CN/latest/7.WebDriver%20API/

2.可以使用 splinter 加载,Splinter 是用 Python 开发的一个开源web自动化测试的工具集。 它可以帮你自动化浏览器的行为,比如浏览 URLs 并和页面进行交互。类似selenium,常规网站操作交互都有。splinter官方文档: https://splinter-docs-zh-cn.readthedocs.io/zh/latest/

如:

from splinter import Browser

import time

url = "http://baidu.com"
# browser = Browser('chrome', headless=True)
browser = Browser('chrome')
browser.visit(url)
# 找到并点击搜索按钮
button = browser.find_by_xpath('//input[@type="submit"]')
# 与元素交互
button.click()
print(browser.html)
time.sleep(30)

3.Scrapy Splash 用来爬取动态网页,其效果和scrapy selenium phantomjs一样,Scrapy Splash是lua脚本写的一个js渲染服务,通过渲染js得到动态网页然后实现网页解析,Splash是官推的js渲染引擎,和Scrapy结合比较好,使用的是webkit开发的轻量级无界面浏览器,渲染之后结果和静态爬取一样可以直接用xpath处理。只是splash是在docker中运行。Scrapy Splash官方文档:https://splash-cn-doc.readthedocs.io/zh_CN/latest/scrapy-splash-toturial.html

代码示例:

settings文件设置

import scrapy
import time
import requests
import json
from qctt.items import toutiaoAuthorItem
import os
from qctt.sqlManager import MySQLManager
import random
from scrapy_splash import SplashRequest
from  scrapy.crawler import CrawlerProcess
from qctt.settings import *
from qctt.Utils import *


script1 = """
function main(splash, args)
  splash:go(args.url)
  local scroll_to = splash:jsfunc("window.scrollTo")
  scroll_to(0, 5000)
  splash:set_viewport_full()
  return {png=splash:png()}
end

"""
class ToutiaoNewsSpider(scrapy.Spider):
    name = 'toutiaoNews'

    def start_requests(self):
        urls=["https://www.toutiao.com/c/user/3434439868/#mid=3443995426",
              "https://www.toutiao.com/c/user/4280517202/#mid=4280698022",
              "https://www.toutiao.com/c/user/6263094546/#mid=6260524942"]
        for url  in urls:
            meta={'author':"test"}
            yield SplashRequest(url=url,
                                callback=self.parseNewsList,
                                args={'wait': 1},
                                endpoint='render.html',
                                meta=meta
                                )


    #解析搜索结果
    def parseNewsList(self, response):
        # print(response.text)
        lis = response.xpath('*//div[@class="relatedFeed"]/ul/li')
        # print(lis)
        mediaName =response.meta['author']
        for li in lis:
            try:
                title = li.xpath(
                    './/div[@class="title-box"]/a/text()').extract_first()
                href = li.xpath(
                    './/div[@class="title-box"]/a/@href').extract_first()
                readCount = li.xpath(
                    './/div[@class="y-left"]/a[@class="lbtn"]/text()').extract_first()

                commentCount = li.xpath(
                    './/div[@class="y-left"]/a[@class="lbtn comment"]/text()').extract_first()

                publishTime = li.xpath(
                    './/div[@class="y-left"]/span/text()').extract_first()
                publishTime = publishTime.replace('⋅ ', '')
                newsids = href.split('/')
                newsid = newsids[2]
                newsurl = 'https://www.toutiao.com/i' + newsid
                print(title)
                print(href)
                print(readCount)
                print(publishTime)
                print(commentCount)
                print(newsurl)


            except Exception as e:
                print(e)

    #从url解析用户id和媒体id
    def getuserIdAndmediaId(sefl,url):
        info = url.split('&user_id=')[1]
        userId = info.split('&')[0]
        mediaInfo = info.split('&')[-1]
        mediaId = mediaInfo.split('media_id=')[1]
        # print(userId,mediaId)
        return  userId,mediaId


#函数主入口,测试使用
if __name__ == "__main__":
    process = CrawlerProcess({'USER_AGENT':'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1)'})
    process.crawl(ToutiaoNewsSpider)
    process.start()

有问题可以评论区留言交流。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨「83」

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值