【问题标题】:Python lxml webscraping Google only printing empty listsPython lxml webscraping Google 只打印空列表
【发布时间】:2015-03-16 09:48:42
【问题描述】:

我一直在寻找解决这个问题的方法,但我一辈子都想不通!

这是我第一次尝试在 python 中编写任何东西,我希望我的脚本从文本文件中加载主题列表,生成 Google 搜索 URL,然后逐个抓取这些 URL 以输出数量的“找到的结果:”根据谷歌,除了前 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 搜索的结构:

任何帮助将不胜感激 - 因为我完全不知道为什么会发生这种情况。

编辑:

看来我的脚本正在触及 Google 的反机器人保护措施,并且 path.content 显示的消息类似于“此页面检查是否真的是您发送请求,而不是机器人。”

我不确定是否有简单的方法可以绕过这个问题,但如果我找到了,我会更新。

【问题讨论】:

  • 如果这是你第一次尝试用 Python 写任何东西,我强烈建议你用更小的东西写……甚至像 HelloWorld在您尝试实现这一目标之前。
  • 我对 RoR 非常熟悉,并且很长一段时间以来一直在使用各种类似的语言进行编码,Python 似乎很简单——对我来说,这就是我为我的“hello world!”选择的。等效练习:) 不过谢谢-我非常感谢您的建议!我可能会后退一步,但有一种感觉,我只是在语法上遗漏了一些东西,或者我试图在没有转换为正确格式的情况下打印一些东西。
  • 不要粗鲁,这只是因为我从你的代码中闻到了重复性......无论如何,你应该尝试将你的代码分解成更小的块,看看 WHICH 部分没有返回预期结果。还要检查你的 Xpath 看看它们是否真的在工作。
  • 不不,这完全没问题,我非常感谢您的建议!您是对的,因为我需要整理代码的效率并为打印实现一些更智能的循环,尽管在我知道我的输出正常工作后我打算这样做。我已经查看了打印路径变量,以接收“”(但是我不确定这是否可取)。还查看了 firebug 并验证了我的 Xpath 是正确的,尽管所有迹象都表明它们是正确的。仍然不确定,但会继续拆开它:)
  • 另外,另一个强烈的建议,尝试从 python 控制台执行 - 从加载文件开始 => 成功 => 迭代行并检查内容 => 然后使用 requests 从 google 获取结果 => 检查 page.content/text => 执行 xpath 等。

标签: python web-scraping lxml python-requests


【解决方案1】:

问题是您没有指定user-agent。您需要发送user-agent,这将充当“真实”用户访问。当机器人或浏览器发送虚假的用户代理字符串以宣布自己为不同的客户端时。因为default requests user-agent is python-requests 和 Google 理解它,所以阻止了请求,并且您收到不同的 HTML,其中包含您的代码无法识别和找到的不同元素的错误。

你可以在我写的关于how to reduce the chance of being blocked while web scraping.的博文中了解更多信息

通过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)

另外,您可以在 for 循环中迭代所有这些,而不是创建 15 个resultUrlList

# .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']

代码和example in the online 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
'''

或者,您可以使用来自 SerpApi 的 Google Organic Results API 来实现相同的目的。这是一个带有免费计划的付费 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 工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    相关资源
    最近更新 更多