Как извлечь «entry.id » из формы Google с использованием Beautiful Soup?

#python #html #beautifulsoup #google-forms

#python #HTML #beautifulsoup #google-формы

Вопрос:

Я пытаюсь автоматизировать форму Google. Я извлек текст ввода, используя следующий код:

 import requests
from bs4 import BeautifulSoup
r=requests.get('https://docs.google.com/forms/d/e/1FAIpQLScio8_OkrBe7wtmw8GeUENvLFVUCAV6eyFOLWhfDbPuunG0Yw/viewform')
cont = BeautifulSoup(r.text,"lxml")
vals = cont.find_all('div', {'class':'freebirdFormviewerComponentsQuestionBaseTitle exportItemTitle freebirdCustomFont'})
print(vals[0].text)
  

Результат: ‘Name’

Но я не могу извлечь entry.id из:

 <div jsname="06bZLc">
    <input type="hidden" name="entry.2005620554" value>
    <input type="hidden" name="entry.1045781291" value>
    <input type="hidden" name="entry.1065046570" value>
    <input type="hidden" name="entry.1166974658" value>
    <input type="hidden" name="entry.839337160" value>
</div>
  

Я попытался использовать следующий код:

 v = cont.find('div', {'jsname': 'o6bZLc'})
x = v.find_all('input')
y = v.find_all_next('input',{'type':'hidden'})
print(x)
print(y)
  

Результат :

 []
[<input name="fvv" type="hidden" value="1"/>, <input name="draftResponse" type="hidden" value='[null,null,"-1617617719642916240"]
'/>, <input name="pageHistory" type="hidden" value="0"/>, <input name="fbzx" type="hidden" value="-1617617719642916240"/>]
  

Но я не мог получить детей внутри <div jsname="06bZLc"> .
Не могли бы вы, пожалуйста, помочь мне получить эти дочерние элементы.

URL: ссылка на форму

Ответ №1:

Идентификаторы добавляются динамически с помощью JavaScript, поэтому BeautifulSoup их не видит. Вы можете попробовать этот пример, чтобы загрузить их:

 import re
import json
import requests


url = 'https://docs.google.com/forms/d/e/1FAIpQLScio8_OkrBe7wtmw8GeUENvLFVUCAV6eyFOLWhfDbPuunG0Yw/viewform'
html_data = requests.get(url).text

data = json.loads( re.search(r'FB_PUBLIC_LOAD_DATA_ = (.*?);', html_data, flags=re.S).group(1) )

def get_ids(d):
    if isinstance(d, dict):
        for k, v in d.items():
            yield from get_ids(v)
    elif isinstance(d, list):
        if len(d) == 3 and d[1] is None:
            yield d[0]
        else:
            for v in d:
                yield from get_ids(v)

# uncomment this to print all data:
# print(json.dumps(data, indent=4))

for i in get_ids(data):
    print(i)
  

С принтами:

 2005620554
1065046570
1166974658
839337160
  

Комментарии:

1. Он вернул только 4 значения, но он должен вернуть все значения 5 записей. можете ли вы проверить это еще раз, пожалуйста

2. Я понял, что спасибо, брат. Я только что заменил len (d)==3 на len (d)>1

Ответ №2:

Пожалуйста, проверьте это

 from bs4 import BeautifulSoup 
html="""<div jsname="06bZLc">
    <input type="hidden" name="entry.2005620554" value>
    <input type="hidden" name="entry.1045781291" value>
    <input type="hidden" name="entry.1065046570" value>
    <input type="hidden" name="entry.1166974658" value>
    <input type="hidden" name="entry.839337160" value>
</div>"""
soup = BeautifulSoup(html,"lxml")
divs = soup.find_all("input")
for i in divs:
    print ((i.attrs['name']).split(".")[1])
  

Вывод: 2005620554 1045781291 1065046570 1166974658 839337160

Отредактируйте, используя предоставленную вами ссылку на форму Google

 import requests
from bs4 import BeautifulSoup
r=requests.get('https://docs.google.com/forms/d/e/1FAIpQLScio8_OkrBe7wtmw8GeUENvLFVUCAV6eyFOLWhfDbPuunG0Yw/viewform')
cont = BeautifulSoup(r.text,"lxml")
divs = soup.find_all("input")
for i in divs:
    print ((i.attrs['name']).split(".")[1])
  

Вывод: 2005620554 1045781291 1065046570 1166974658 839337160

Редактировать на основе 2-го комментария

 import requests
from bs4 import BeautifulSoup
r=requests.get('https://docs.google.com/forms/d/e/1FAIpQLScio8_OkrBe7wtmw8GeUENvLFVUCAV6eyFOLWhfDbPuunG0Yw/viewform')
cont = BeautifulSoup(r.text,"lxml")
divs = soup.find_all("input")
nums=[]
for i in divs:
    nums.extend((i.attrs['name']).split("."))
num=[int(i) for i in nums if i.isdigit()]
  

Вывод: [2005620554 1045781291 1065046570 1166974658 839337160]

Комментарии:

1. Но вы используете жестко запрограммированный ответ, если сайт изменится, код сломается, а также вы используете жестко запрограммированный HTML-документ.

2. хотя ваш этот отредактированный фрагмент кода также закодирован, потому что вы используете позицию индекса второго появления полей ввода, если менеджер сайта изменит позицию, код немедленно прервется.

3. очень хорошо проверено, поэтому прокомментировал редактирование.

4. @Karthik сэр, я получаю ошибку ключа: ‘name’, не могли бы вы помочь

5. @UjjalBaniya Пожалуйста, проверьте, правильно ли вы использовали кавычки, и используйте фрагмент 2-го редактирования