Python lxml webscraping Google печатает только пустые списки

Я искал решение этой проблемы, но, судя по всему, не могу понять!

Это моя первая попытка написать что-нибудь на python, и я хочу, чтобы мой скрипт загружал список субъектов из текстового файла, генерировал URL-адрес для поиска в Google и очищал эти URL-адреса один за другим, чтобы вывести количество результатов. Найдено: "По данным Google, в дополнение к ссылкам из 15 лучших результатов.

Моя проблема в том, что когда я запускаю свой код, все, что печатается, это пустые списки:

[]


[]


[]


[]


[]


[]


[]


[]


[]


[]


[]


[]


[]


[]


[]


[]


**END_OBJECT** 

..etc.

Вот мой код:

from lxml import html
import requests



def iterate():
    with open("list.txt", "r") as infile:
        for line in infile:
            if not line.strip():
                break
            yield line

output = open ("statistic_out.txt", "w")

for line in iterate():
    raw = line
    output.write(raw + " services")
    request = raw.replace(" ", "%20")
    page = requests.get('https://www.google.com.au/search?safe=off&tbs=ctr:countryAU&cr=countryAU&q=' + request + 'services%20-yellowpages%20-abs', verify=False)
    path = html.fromstring(page.text)
    #This will create a list of buyers:
    resultCount = path.xpath('//*[@id="resultStats"]/text()')
    #This will create a list of prices
    print(resultCount)
    print('\n')
    resultUrlList1 = path.xpath('//*[@id="rso"]/div[2]/li[1]/div/h3/a/text()')
    resultUrlList2 = path.xpath('//*[@id="rso"]/div[2]/li[2]/div/h3/a/text()')
    resultUrlList3 = path.xpath('//*[@id="rso"]/div[2]/li[3]/div/h3/a/text()')
    resultUrlList4 = path.xpath('//*[@id="rso"]/div[2]/li[4]/div/h3/a/text()')
    resultUrlList5 = path.xpath('//*[@id="rso"]/div[2]/li[5]/div/h3/a/text()')
    resultUrlList6 = path.xpath('//*[@id="rso"]/div[2]/li[6]/div/h3/a/text()')
    resultUrlList7 = path.xpath('//*[@id="rso"]/div[2]/li[7]/div/h3/a/text()')
    resultUrlList8 = path.xpath('//*[@id="rso"]/div[2]/li[8]/div/h3/a/text()')
    resultUrlList9 = path.xpath('//*[@id="rso"]/div[2]/li[9]/div/h3/a/text()')
    resultUrlList10 = path.xpath('//*[@id="rso"]/div[2]/li[10]/div/h3/a/text()')
    resultUrlList11 = path.xpath('//*[@id="rso"]/div[2]/li[11]/div/h3/a/text()')
    resultUrlList12 = path.xpath('//*[@id="rso"]/div[2]/li[12]/div/h3/a/text()')
    resultUrlList13 = path.xpath('//*[@id="rso"]/div[2]/li[13]/div/h3/a/text()')
    resultUrlList14 = path.xpath('//*[@id="rso"]/div[2]/li[14]/div/h3/a/text()')
    resultUrlList15 = path.xpath('//*[@id="rso"]/div[2]/li[15]/div/h3/a/text()')
    print(resultUrlList1)
    print('\n')
    print(resultUrlList2)
    print('\n')
    print(resultUrlList3)
    print('\n')
    print(resultUrlList4)
    print('\n')
    print(resultUrlList5)
    print('\n')
    print(resultUrlList6)
    print('\n')
    print(resultUrlList7)
    print('\n')
    print(resultUrlList8)
    print('\n')
    print(resultUrlList9)
    print('\n')
    print(resultUrlList10)
    print('\n')
    print(resultUrlList11)
    print('\n')
    print(resultUrlList12)
    print('\n')
    print(resultUrlList13)
    print('\n')
    print(resultUrlList14)
    print('\n')
    print(resultUrlList15)
    print('\n')
    print("**END_OBJECT** \n")

Фактическая структура HTML такая же, как у любого поиска Google:HTML структура

Любая помощь будет принята с благодарностью - так как я совершенно потерян, почему это происходит.

РЕДАКТИРОВАТЬ:

Похоже, что мой скрипт затрагивает анти-бот защиты Google, а path.content показывает сообщения в духе "Эта страница проверяет, действительно ли вы отправляете запросы, а не робот".

Я не уверен, есть ли простые способы обойти это, хотя обновлю, если я найду любой.

1 ответ

Проблема в том, что вы не указываете расширение. Вам нужно отправить, который будет действовать как «настоящий» пользовательский визит. Когда бот или браузер отправляет фальшивую строку пользовательского агента, чтобы объявить себя другим клиентом. Потому что по умолчанию requests- это python-запросы, и Google это понимает, блокирует запросы, и вы получаете другой HTML-код с ошибкой, который содержит разные элементы, которые ваш код не может распознать и найти.

Вы можете узнать больше об этом в сообщении блога, которое я написал о том, как снизить вероятность блокировки при парсинге веб-страниц.

Проходить user-agent:

      headers = {
    'User-agent':
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582'
}

requests.get('URL', headers=headers)

Кроме того, вместо создания 15 resultUrlList, вы можете перебрать их все в for петля:

      # .tF2Cxc CSS selector is a container with title, link and other data
for result in soup.select('.tF2Cxc'):
  title = result.select_one('.DKV0Md').text
  link = result.select_one('.yuRUbf a')['href']

Код и пример в онлайн-среде IDE:

      from bs4 import BeautifulSoup
import requests, lxml

headers = {
    'User-agent':
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582'
}

params = {
  'q': 'how to create minecraft server',
  'gl': 'us',
  'hl': 'en',
}

html = requests.get('https://www.google.com/search', headers=headers, params=params)
soup = BeautifulSoup(html.text, 'lxml')

for result in soup.select('.tF2Cxc'):
  title = result.select_one('.DKV0Md').text
  link = result.select_one('.yuRUbf a')['href']
  print(title, link, sep='\n')


----------
'''
How to Setup a Minecraft: Java Edition Server – Home
https://help.minecraft.net/hc/en-us/articles/360058525452-How-to-Setup-a-Minecraft-Java-Edition-Server
Minecraft Server Download
https://www.minecraft.net/en-us/download/server
Setting Up Your Own Minecraft Server - iD Tech
https://www.idtech.com/blog/creating-minecraft-server
# other results
'''

В качестве альтернативы вы можете добиться того же, используя Google Organic Results API от SerpApi. Это платный API с бесплатным тарифным планом.

Разница в вашем случае заключается в том, что вам не нужно думать, как заставить все работать: как обходить блоки, как извлекать данные, как поддерживать скрипт с течением времени, если что-то в HTML будет изменено и т. Д. Вместо этого вы только нужно перебрать структурированный JSON и получить нужные данные.

Код для интеграции:

      import os
from serpapi import GoogleSearch

params = {
  "engine": "google",
  "q": "how to create minecraft server",
  "hl": "en",
  "gl": "us",
  "api_key": os.getenv("API_KEY"),
}

search = GoogleSearch(params)
results = search.get_dict()

for result in results["organic_results"]:
  print(result['title'])
  print(result['link'])

----------
'''
How to Setup a Minecraft: Java Edition Server – Home
https://help.minecraft.net/hc/en-us/articles/360058525452-How-to-Setup-a-Minecraft-Java-Edition-Server
Minecraft Server Download
https://www.minecraft.net/en-us/download/server
Setting Up Your Own Minecraft Server - iD Tech
https://www.idtech.com/blog/creating-minecraft-server
# other results
'''

Отказ от ответственности, я работаю на SerpApi.

Другие вопросы по тегам