战忽地狱猫 发表于 2020-7-19 13:51

python问卷星爬虫bug求助

本帖最后由 战忽地狱猫 于 2020-7-19 16:02 编辑




###原bug
`MaxRetryError: HTTPConnectionPool(host='127.0.0.1', port=9659): Max retries exceeded with url: /session/14150baedf86c6930897efe3675806f3/element (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000204D3E95B70>: Failed to establish a new connection: 由于目标计算机积极拒绝,无法连接。'))`
### 已解决:解决办法**把打开浏览器执行自动填写后关闭改为打开标签页执行自动填写并关闭(先打开一个主标签页,然后打开副标签页进行问卷自动填写)**
**代码暂时只有单选和填空功能,期中填空为默认文本:没有**### 配置环境:
***

> slenium库,调用的对应浏览器驱动,此处为Chrome
>
> 解压后放在python目录下
浏览器驱动下载链接
http://chromedriver.storage.googleapis.com/index.html

[使用python实现问卷星自动答题功能——基础篇]

(对标签解析)

>
>
>random库实现随机选择
>
>定位题目对应标签
>
>```
>from selenium import webdriver
>import random
>打开问卷星
>driver = webdriver.Chrome()
>driver.get('https://www.wjx.cn/jq/22452252.aspx')
>```
>
>### 利用CSS选择器对页面进行解析
>
>###### 我们发现,我们所有的题目的回答的选项的标签都在li标签里面,所以我们找到li标签。ans=answer.find_elements_by_css_selector(‘li’)
>
>```python
>####先滑到标签再去点击
>driver.execute_script("arguments.scrollIntoView();",answer)
>### 找到标签
>ans=answer.find_elements_by_css_selector('li')
>lsans=random.choice(ans)
>   lsans.click()
>```
>
>填空题:标签为textarea
>
>```python
>`if not ans:
>         text=answer.find_element_by_css_selector('textarea')
>         text.send_keys('没有')
>         continue`
>```
>
>提交问卷选项
>
>```python
>am=driver.find_element_by_css_selector('#submit_button')
>am.click()   
>```

>#### 但是我们要想实现快速的填写,我们还得进行浏览器的关闭(因为浏览器开一次只能填一次,所以可以让它自动关闭),然后我们在使用一个循环,进行不断的开关浏览器,即可实现不停的填写问卷
>
>```python
>driver.quit()
>```



> ### 进一步:利用try catch跳过无法作答的题避免死循环
>
> 首先我们获得了answer之后,我们得避免一些问题导致我们的代码出现红字,于是我们使用try来避免报错(这个原因是,**有些题目我们不能作答,但是使用死的代码会发生卡死的现象**。)举个简单的例子,当我们遇到一个分叉的时候,**比如有的题目,你选了否就会答第五题,选了是就会答第六题,这样子虽然我们会获取到五和六的题目的div,但是却不能两者都答**,如果不使用try的话,会导致代码报错不能运行,我们使用try这样子就可以保持即使这题答不了,也只会把异常抛出,然后我们依然会往后做(这样子就从另一个角度来解决了分叉的问题)。

### 进一步:模拟滑动浏览器

>
>
>因为问卷星肯定不是只有几题的,肯定是有很多道题的,**所以我们要滑动浏览器**(因为我们使用的点击只是模仿人的操作,人肯定是不能到自己看不到的地方答题的)使用**driver.execute_script(“arguments.scrollIntoView();”,answer)来进行浏览器的滑动**



### 思路一完整代码

```python
from selenium import webdriver
import random
driver = webdriver.Chrome()
driver.get('https://www.wjx.cn/jq/22452252.aspx')
answers = driver.find_elements_by_css_selector('.div_question')
for i in range(5):
    for answer in answers:
      try:
            ####先滑到标签再去点击
            driver.execute_script("arguments.scrollIntoView();",answer)
            ### 找到标签
            ans=answer.find_elements_by_css_selector('li')
            if not ans:
                text=answer.find_element_by_css_selector('textarea')
                text.send_keys('没有')
                continue
            lsans=random.choice(ans)
            lsans.click()
      except Exception as e:
            print(e)
    am=driver.find_element_by_css_selector('#submit_button')
    am.click()   
    driver.quit()
   
   
```

### 运行结果报错

> 第一次成功打开Chrome浏览器填写并退出,后台有提交记录
>
> 填写了单选和,后四次未执行成功
>
> 报错



`MaxRetryError: HTTPConnectionPool(host='127.0.0.1', port=9659): Max retries exceeded with url: /session/14150baedf86c6930897efe3675806f3/element (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000204D3E95B70>: Failed to establish a new connection: 由于目标计算机积极拒绝,无法连接。'))`
```
# -*- coding: utf-8 -*-
## kof21411大佬解决bug后的代码
"""
Created on Sun Jul 19 15:39:40 2020

@author: Lenovo
"""

from selenium import webdriver

import random

driver = webdriver.Chrome()

# driver = webdriver.Chrome(executable_path="C:/chromedriver.exe")

driver.get('https://www.baidu.com')



for i in range(5):

    js = "window.open('https://www.wjx.cn/jq/85695920.aspx')"

    driver.execute_script(js)

    # driver.get('https://www.wjx.cn/jq/22452252.aspx')

    handlers =driver.window_handles

    driver.switch_to_window(handlers)

    answers = driver.find_elements_by_css_selector('.div_question')

    for answer in answers:

      try:

            ####先滑到标签再去点击

            driver.execute_script("arguments.scrollIntoView();",answer)

            ### 找到标签

            ans=answer.find_elements_by_css_selector('li')

            if not ans:

                text=answer.find_element_by_css_selector('textarea')

                text.send_keys('没有')

                continue

            lsans=random.choice(ans)

            lsans.click()

      except Exception as e:

            print(e)

    # am=driver.find_element_by_css_selector('#submit_button')

    # am.click()   

    driver.close()

    driver.switch_to_window(handlers)

driver.quit()

```



kof21411 发表于 2020-7-19 14:02

兄弟,你的逻辑出错了,你要循环执行五次,但在第一次执行完就已经driver.quit(),后面四次是无法执行的,所以就报错了

战忽地狱猫 发表于 2020-7-19 14:09

本帖最后由 战忽地狱猫 于 2020-7-19 14:11 编辑

kof21411 发表于 2020-7-19 14:02
兄弟,你的逻辑出错了,你要循环执行五次,但在第一次执行完就已经driver.quit(),后面四次是无法执行的, ...
浏览器开一次只能填一次,所以要先关掉来着
我刚刚试着在循环的关闭后面加了一句
driver.quit()
driver.get('https://www.wjx.cn/jq/85695920.aspx')
结果就是还是和上面一样的报错

kof21411 发表于 2020-7-19 14:12

战忽地狱猫 发表于 2020-7-19 14:09
kof21411 发表于 2020-7-19 14:02
兄弟,你的逻辑出错了,你要循环执行五次,但在第一次执行完就已经drive ...

那你就应该这样写:
from selenium import webdriver
import random
driver = webdriver.Chrome()

for i in range(5):
    driver.get('https://www.wjx.cn/jq/22452252.aspx')
    answers = driver.find_elements_by_css_selector('.div_question')
    for answer in answers:
      try:
            ####先滑到标签再去点击
            driver.execute_script("arguments.scrollIntoView();",answer)
            ### 找到标签
            ans=answer.find_elements_by_css_selector('li')
            if not ans:
                text=answer.find_element_by_css_selector('textarea')
                text.send_keys('没有')
                continue
            lsans=random.choice(ans)
            lsans.click()
      except Exception as e:
            print(e)
    am=driver.find_element_by_css_selector('#submit_button')
    am.click()   
    driver.quit()
打开五次,关闭五次

战忽地狱猫 发表于 2020-7-19 14:15

kof21411 发表于 2020-7-19 14:12
那你就应该这样写:
from selenium import webdriver
import random


嗯嗯,这个应该是我逻辑错了,但是这个改完还是报了和原来一样的bug{:301_972:}
感觉可能是connection超额,但是不知道怎么改

kof21411 发表于 2020-7-19 14:49

战忽地狱猫 发表于 2020-7-19 14:15
嗯嗯,这个应该是我逻辑错了,但是这个改完还是报了和原来一样的bug
感觉可能是connection超 ...

主要逻辑代码帮你写好了,可以正常打开五次关闭五次了,你只要细化一下中间元素的选取就可以了
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver
import random
driver = webdriver.Chrome()
# driver = webdriver.Chrome(executable_path="C:/chromedriver.exe")
driver.get('https://www.baidu.com')

for i in range(5):
    js = "window.open('https://www.wjx.cn/jq/22452252.aspx')"
    driver.execute_script(js)
    # driver.get('https://www.wjx.cn/jq/22452252.aspx')
    handlers =driver.window_handles
    driver.switch_to_window(handlers)
    answers = driver.find_elements_by_css_selector('.div_question')
    for answer in answers:
      try:
            ####先滑到标签再去点击
            driver.execute_script("arguments.scrollIntoView();",answer)
            ### 找到标签
            ans=answer.find_elements_by_css_selector('li')
            if not ans:
                text=answer.find_element_by_css_selector('textarea')
                text.send_keys('没有')
                continue
            lsans=random.choice(ans)
            lsans.click()
      except Exception as e:
            print(e)
    # am=driver.find_element_by_css_selector('#submit_button')
    # am.click()   
    driver.close()
    driver.switch_to_window(handlers)
driver.quit()

战忽地狱猫 发表于 2020-7-19 15:42

kof21411 发表于 2020-7-19 14:49
主要逻辑代码帮你写好了,可以正常打开五次关闭五次了,你只要细化一下中间元素的选取就可以了


多谢大佬
请问为什么把关闭浏览器重新打开改为关闭标签页就好了啊
我还以为报错是因为connetion数量超了之类的

kof21411 发表于 2020-7-19 15:46

战忽地狱猫 发表于 2020-7-19 15:42
多谢大佬
请问为什么把关闭浏览器重新打开改为关闭标签页就好了啊
我还以为报错是因为connetion数量超 ...

因为使用quit方法,整个浏览器都直接关闭,ChromeDriver进程也会被结束。
ChromeDriver进程结束,你再也不能操了,所以只能用close()方法关闭新建的标签页
页: [1]
查看完整版本: python问卷星爬虫bug求助