Selenium+代理爬取需要模仿用户交互的网站

打印 上一主题 下一主题

主题 1734|帖子 1734|积分 5202

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在一样平常爬虫采集网站的过程中,部分数据价值较高的网站,会限制访客的访问举动。这种时候发起通过登录的方式,获取目的网站的cookie,然后再使用cookie配合代理IP进行数据采集分析。本日我们就先容下如何使用Selenium库来爬取网页数据,特别是那些需要模仿用户交互的动态网页。
Selenium是一个自动化测试工具,它可以模仿用户在浏览器中的操作,比如点击按钮、填写表单等。与常用的BeautifulSoup、requests等爬虫库不同,Selenium可以处理JavaScript动态加载的内容,因此对于那些需要模仿用户交互才气获取的数据,Selenium是一个非常合适的选择。
通过联合Selenium的各种功能,我们可以编写强盛的网络爬虫来爬取各种网站上的数据。但请注意,在进行网络爬虫时,务必遵守目的网站的robots.txt规定,并恭敬网站的数据抓取政策。另外,过于频仍的爬取大概会给网站带来负担,甚至触发反爬机制,因此发起在爬取数据的过程中做好反爬措施,比如这里我们以访问知乎为例,通过获取网站的cookie在配合使用代理IP进行采集。关于代理IP一直都是爬虫小搭档们询问的题目,网上代理虽然多,但是优质的却很少,这里推荐有优质代理需求的可以试试亿牛云代理,提供的方式不仅有传统的api模式,还有隧道转发,发起大家都试试隧道转发,使用简单,方便,节约许多的时间去研究爬虫反爬机制。
这里我们就使用Selenium通过添加隧道转发代理访问知乎为例给大家提供一个参考:
  1.     import os
  2.     import time
  3.     import zipfile
  4.     from selenium import webdriver
  5.     from selenium.common.exceptions import TimeoutException
  6.     from selenium.webdriver.common.by import By
  7.     from selenium.webdriver.support import expected_conditions as EC
  8.     from selenium.webdriver.support.ui import WebDriverWait
  9.     class GenCookies(object):
  10.         # 随机useragent
  11.         USER_AGENT = open('useragents.txt').readlines()
  12.         # 代理服务器(产品官网 www.16yun.cn)
  13.         PROXY_HOST = 't.16yun.cn'  #  proxy or host
  14.         PROXY_PORT = 31111  # port
  15.         PROXY_USER = 'USERNAME'  # username
  16.         PROXY_PASS = 'PASSWORD'  # password
  17.         @classmethod
  18.         def get_chromedriver(cls, use_proxy=False, user_agent=None):
  19.             manifest_json = """
  20.             {
  21.                 "version": "1.0.0",
  22.                 "manifest_version": 2,
  23.                 "name": "Chrome Proxy",
  24.                 "permissions": [
  25.                     "proxy",
  26.                     "tabs",
  27.                     "unlimitedStorage",
  28.                     "storage",
  29.                     "<all_urls>",
  30.                     "webRequest",
  31.                     "webRequestBlocking"
  32.                 ],
  33.                 "background": {
  34.                     "scripts": ["background.js"]
  35.                 },
  36.                 "minimum_chrome_version":"22.0.0"
  37.             }
  38.             """
  39.             background_js = """
  40.             var config = {
  41.                     mode: "fixed_servers",
  42.                     rules: {
  43.                     singleProxy: {
  44.                         scheme: "http",
  45.                         host: "%s",
  46.                         port: parseInt(%s)
  47.                     },
  48.                     bypassList: ["localhost"]
  49.                     }
  50.                 };
  51.             chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
  52.             function callbackFn(details) {
  53.                 return {
  54.                     authCredentials: {
  55.                         username: "%s",
  56.                         password: "%s"
  57.                     }
  58.                 };
  59.             }
  60.             chrome.webRequest.onAuthRequired.addListener(
  61.                         callbackFn,
  62.                         {urls: ["<all_urls>"]},
  63.                         ['blocking']
  64.             );
  65.             """ % (cls.PROXY_HOST, cls.PROXY_PORT, cls.PROXY_USER, cls.PROXY_PASS)
  66.             path = os.path.dirname(os.path.abspath(__file__))
  67.             chrome_options = webdriver.ChromeOptions()
  68.             # 关闭webdriver的一些标志
  69.             # chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])        
  70.             if use_proxy:
  71.                 pluginfile = 'proxy_auth_plugin.zip'
  72.                 with zipfile.ZipFile(pluginfile, 'w') as zp:
  73.                     zp.writestr("manifest.json", manifest_json)
  74.                     zp.writestr("background.js", background_js)
  75.                 chrome_options.add_extension(pluginfile)
  76.             if user_agent:
  77.                 chrome_options.add_argument('--user-agent=%s' % user_agent)
  78.             driver = webdriver.Chrome(
  79.                 os.path.join(path, 'chromedriver'),
  80.                 chrome_options=chrome_options)
  81.             # 修改webdriver get属性
  82.             # script = '''
  83.             # Object.defineProperty(navigator, 'webdriver', {
  84.             # get: () => undefined
  85.             # })
  86.             # '''
  87.             # driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": script})
  88.             return driver
  89.         def __init__(self, username, password):        
  90.             # 登录example网站
  91.             self.url = 'https://passport.example.cn/signin/login?entry=example&r=https://m.example.cn/'
  92.             self.browser = self.get_chromedriver(use_proxy=True, user_agent=self.USER_AGENT)
  93.             self.wait = WebDriverWait(self.browser, 20)
  94.             self.username = username
  95.             self.password = password
  96.         def open(self):
  97.             """
  98.             打开网页输入用户名密码并点击
  99.             :return: None
  100.             """
  101.             self.browser.delete_all_cookies()
  102.             self.browser.get(self.url)
  103.             username = self.wait.until(EC.presence_of_element_located((By.ID, 'loginName')))
  104.             password = self.wait.until(EC.presence_of_element_located((By.ID, 'loginPassword')))
  105.             submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'loginAction')))
  106.             username.send_keys(self.username)
  107.             password.send_keys(self.password)
  108.             time.sleep(1)
  109.             submit.click()
  110.         def password_error(self):
  111.             """
  112.             判断是否密码错误
  113.             :return:
  114.             """
  115.             try:
  116.                 return WebDriverWait(self.browser, 5).until(
  117.                     EC.text_to_be_present_in_element((By.ID, 'errorMsg'), '用户名或密码错误'))
  118.             except TimeoutException:
  119.                 return False
  120.         def get_cookies(self):
  121.             """
  122.             获取Cookies
  123.             :return:
  124.             """
  125.             return self.browser.get_cookies()
  126.         def main(self):
  127.             """
  128.             入口
  129.             :return:
  130.             """
  131.             self.open()
  132.             if self.password_error():
  133.                 return {
  134.                     'status': 2,
  135.                     'content': '用户名或密码错误'
  136.                 }            
  137.             cookies = self.get_cookies()
  138.             return {
  139.                 'status': 1,
  140.                 'content': cookies
  141.             }
  142.     if __name__ == '__main__':
  143.         result = GenCookies(
  144.             username='180000000',
  145.             password='16yun',
  146.         ).main()
  147.         print(result)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表