爬虫:记一次失败的尝试

        近日有一个小练习,要从XXX网站上爬取特定的查询结果(仅是练习爬虫,没有任何其他用意~~)。兴冲冲的就拿来selenium开始上手。不料出师不利,屡遭挫折,历经了很长一段时间的suffer后,最终也是功亏一篑。

        这时才知道,这个网站有过被爬虫师傅爬崩掉的一段不堪回首的往事,已经做了很高级的反爬。到底高不高级不清楚,但对我这个小白来说也是一座不是那么容易翻过的高山了。

        但回首自己的尝试,又感到有点神奇。故记录一下自己的经历,以供未来参考。欢迎大佬指点迷津。


        本文以笔者尝试爬取xxx网站的过程为线,介绍笔者在使用selenium对该网站进行爬取的每一步的操作与遇到的问题。

        使用:python,版本3.9,chrome浏览器,版本101.0,selenium版本4.1.3


        首先提一下一些普遍的问题,第一点,这个网站的不稳定性,我在手动操作该网站的时候,就遇到过网站返回信息不全面的情况(有时候是登录界面找不到输入框。。。),还有的时候会加载超时,本来以为用IE会好一点,结果也有类似的情况出现,介于IE上能找到的资料也少,还不如chrome方便,于是就决定继续用chrome了。

        还有一个问题是,这个网站在打开开发者工具时会进行无限debugger,阻止你对网站进行调试。可以通过chrome的禁用断点调试功能来处理。

        如果某一个时间段内登录的次数过多,这个网站还会有验证码环节。


       

        首先就要用selenium来打开这个网站。代码如下:

import time,json
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

if __name__ =='__main__':
    s = Service("./chromedriver.exe")

    bro = webdriver.Chrome(service=s)

    bro.get('https://......./')
    
    #bro.close()

        运行一看,能进入,于是使用selenium去点击登录按钮,以进入登录界面,

if __name__ =='__main__':
    s = Service("./chromedriver.exe")

    bro = webdriver.Chrome(service=s)

    bro.get('https://......./')

    
    bro.maximize_window()
    time.sleep(10)
    login = bro.find_element(By.XPATH, '//*[@id="loginLi"]/a')
    login.click()
    #bro.close()

        然后就,非常愉快的返回了400。。。

        

       身为小白的博主便去问度娘,度娘说,可能是浏览器被反爬虫程序识别了,它会检查你的window .navigator .webdriver属性,正常用户登录都是false或undefined,而用selenium就会变成true,我一看,果然是这个样子,于是按度娘说的改了代码。

if __name__ =='__main__':
    s = Service("./chromedriver.exe")

    chrome_options = Options()
    chrome_options.add_argument(
        'user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")

    bro = webdriver.Chrome(service=s,options=chrome_options)

    bro.get('https://......./')


    bro.maximize_window()
    time.sleep(10)
    login = bro.find_element(By.XPATH, '//*[@id="loginLi"]/a')
    login.click()
    #bro.close()

        再次运行,又很愉快的再次返回400。。。

        看了下 window .navigator .webdriver,已经变成false了。

        博主见到这种情况很不知所措,急忙又去问度娘,只见度娘缓缓答道:“清一下cookie试试”。博主立刻遵旨,将代码改成了这样: 

if __name__ =='__main__':
    s = Service("./chromedriver.exe")

    chrome_options = Options()
    chrome_options.add_argument(
        'user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")

    bro = webdriver.Chrome(service=s,options=chrome_options)

    bro.get('https://......./')


    bro.maximize_window()
    time.sleep(10)
    login = bro.find_element(By.XPATH, '//*[@id="loginLi"]/a')

    #这一步删掉了所有的cookie
    bro.delete_all_cookies()

    login.click()
    #bro.close()

        奇迹,发生了,我成功的进入了登录界面。 

        所以就连忙用selenium找到相应的输入框输入账号密码,然后点击登录,成功进入登录后的界面(虽然不知道这次为什么可以不用删除cookie)

        然后就是用selenium在搜索框中输入相应的搜索条件,再点击搜索,然后。。。相同的问题又出现了。

        然而这次不能再像上次一样直接删除所有的cookie了,因为博主这样干了一次后发现博主的登录信息也被删掉了,网站直接回到了登录界面,这就令人非常的难受。

if __name__ =='__main__':
    s = Service("./chromedriver.exe")

    chrome_options = Options()
    chrome_options.add_argument(
        'user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")

    bro = webdriver.Chrome(service=s,options=chrome_options)

    bro.get('https://......./')


    bro.maximize_window()
    time.sleep(10)
    login = bro.find_element(By.XPATH, '//*[@id="loginLi"]/a')

    bro.delete_all_cookies()

    login.click()

    bro.refresh()
    time.sleep(10)

    bro.switch_to.frame('contentIframe')

    phonum = bro.find_element(By.XPATH, '//*[@id="root"]/div/form/div/div[1]/div/div/div/input')
    key = bro.find_element(By.XPATH, '//*[@id="root"]/div/form/div/div[2]/div/div/div/input')
    btn = bro.find_element(By.XPATH, '//*[@id="root"]/div/form/div/div[3]/span')

    phonum.send_keys('请输入您的手机号')
    key.send_keys('请输入您的密码')

    btn.click()
    time.sleep(3)

    bro.switch_to.default_content()

    time.sleep(3)
    btn1 = bro.find_element(By.XPATH, '//*[@id="_view_1540966814000"]/div/div[1]/div[1]')
    btn1.click()
    time.sleep(3)

    input = bro.find_element(By.ID, 'qbValue')
    input.send_keys('江苏广信感光新材料股份有限公司')

    btn2 = bro.find_element(By.ID, 'searchBtn')
    btn2.click()

    #bro.close()

        博主开始想,那cookie就不全不删掉了,就只删掉那些与登录无关的cookie是不是就行了?

        于是博主保存了登录界面的cookie1与登录完成跳转后的页面的cookie2,分别如下:

这是登录页面中的cookie1:

[
{"domain": ".....", "expiry": 1667707332, "httpOnly": false, "name": "_bl_uid", "path": "/", "secure": false, "value": "......"}
,

{"domain": "......", "expiry": 1667880132, "httpOnly": false, "name": "CNZZDATA1278108394", "path": "/", "secure": false, "value": "........"}
,

{"domain": ".........", "expiry": 1667880132, "httpOnly": false, "name": "UM_distinctid", "path": "/", "secure": false, "value": "........."}
,

{"domain": "........", "httpOnly": true, "name": "HOLDONKEY", "path": "/", "sameSite": "None", "secure": true, "value": "..........."}

这是登录后跳转到的页面的cookie2

[
{"domain": ".......", "expiry": 1967515347, "httpOnly": false, "name": "HM4hUBT0dDOn443T", "path": "/", "secure": true, "value": "......"}
,

{"domain": "........", "httpOnly": true, "name": "SESSION", "path": "/", "secure": false, "value": "......."}
,

{"domain": ".......", "expiry": 1667880132, "httpOnly": false, "name": "UM_distinctid", "path": "/", "secure": false, "value": "........."}
,

{"domain": "........", "expiry": 1652155631, "httpOnly": true, "name": "wzws_reurl", "path": "/", "secure": false, "value": "........"}
,

{"domain": "..........", "expiry": 1967515251, "httpOnly": true, "name": "HM4hUBT0dDOn443S", "path": "/", "secure": true, "value": "......."}

         可以看出两个页面的cookie中有一个名为UM_distinctid的cookie是不变的,应该是与用户登录有关的信息,还有一个session的cookie应该也是不能删的。

        于是博主就顺着这个思路删掉了cookie2中的其他三个cookie:

if __name__ =='__main__':
    s = Service("./chromedriver.exe")

    chrome_options = Options()
    chrome_options.add_argument(
        'user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")

    bro = webdriver.Chrome(service=s,options=chrome_options)

    bro.get('https://......./')


    bro.maximize_window()
    time.sleep(10)
    login = bro.find_element(By.XPATH, '//*[@id="loginLi"]/a')

    bro.delete_all_cookies()

    login.click()

    bro.refresh()
    time.sleep(10)

    bro.switch_to.frame('contentIframe')

    phonum = bro.find_element(By.XPATH, '//*[@id="root"]/div/form/div/div[1]/div/div/div/input')
    key = bro.find_element(By.XPATH, '//*[@id="root"]/div/form/div/div[2]/div/div/div/input')
    btn = bro.find_element(By.XPATH, '//*[@id="root"]/div/form/div/div[3]/span')

    phonum.send_keys('请输入您的手机号')
    key.send_keys('请输入您的密码')

    btn.click()
    time.sleep(3)

    bro.switch_to.default_content()

    time.sleep(3)
    btn1 = bro.find_element(By.XPATH, '//*[@id="_view_1540966814000"]/div/div[1]/div[1]')
    btn1.click()
    time.sleep(3)

    input = bro.find_element(By.ID, 'qbValue')
    input.send_keys('江苏广信感光新材料股份有限公司')

    btn2 = bro.find_element(By.ID, 'searchBtn')

    #这里删除多余的cookie
    bro.delete_cookie('HM4hUBT0dDOn443T')
    bro.delete_cookie('wzws_reurl')
    bro.delete_cookie('HM4hUBT0dDOn443S')


    btn2.click()

    #bro.close()

        奇迹又发生了,我成功的进入到了查询结果的界面中!!!

        但博主的任务还没有完成,因为查询的结果有很多页,博主希望能查询到每一页的结果,于是就非常激动的用selenium找到翻页的按钮,结果。。。。熟悉的问题又回来了。翻页的js请求得到了服务器400的响应。

        借助之前成功的经验,博主企图在cookie上在动手脚来获取正常的响应,无奈几经尝试,多次与手动操作进行比较后无果。最后又参考了网上的许多博客上的方法也没有得到解决,只得作罢,将过程记录于此。

        个人学习笔记,如需转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值