【问题标题】:Why is my webscraper not detecting any changes?为什么我的网络爬虫没有检测到任何变化?
【发布时间】:2022-01-16 00:41:45
【问题描述】:

我想用beautifulsoup4 和requests 编写一个websraper。它在特定表上抓取特定表的特定列的数据。它刮一次,等待一段时间,再刮一次,然后比较两个“刮”。如果有差异,则打印"something has changed",如果没有差异,则打印"no changes"

这是完整的代码:

import requests
import time
from bs4 import BeautifulSoup

URL = "https://website.com"
website = requests.get(URL)
soup = BeautifulSoup(website.content, "html.parser")


data = []
table = soup.find("table", class_="table table-bordered table-sm table-responsive")
table_body = table.find('tbody')

rows = table_body.find_all('tr')
for row in rows:
    cols = row.find_all('td')[0]
    cols = [ele.text.strip() for ele in cols]
    data.append([ele for ele in cols if ele]) # Get rid of empty values

    cols2 = row.find_all('td')[1]
    cols2 = [ele.text.strip() for ele in cols2]
    data.append([ele for ele in cols2 if ele])  # Get rid of empty values

    cols3 = row.find_all('td')[2]
    cols3 = [ele.text.strip() for ele in cols3]
    data.append([ele for ele in cols3 if ele])  # Get rid of empty values

    cols4 = row.find_all('td')[3]
    cols4 = [ele.text.strip() for ele in cols4]
    data.append([ele for ele in cols4 if ele])

    cols5 = row.find_all('td')[5]
    cols5 = [ele.text.strip() for ele in cols5]
    data.append([ele for ele in cols5 if ele])


    print(cols, cols2, cols3, cols4, cols5)

time.sleep(600)

for row in rows:
    cols11 = row.find_all('td')[0]
    cols11 = [ele.text.strip() for ele in cols11]
    data.append([ele for ele in cols11 if ele])  # Get rid of empty values

    cols22 = row.find_all('td')[1]
    cols22 = [ele.text.strip() for ele in cols22]
    data.append([ele for ele in cols22 if ele])  # Get rid of empty values

    cols33 = row.find_all('td')[2]
    cols33 = [ele.text.strip() for ele in cols33]
    data.append([ele for ele in cols33 if ele])  # Get rid of empty values

    cols44 = row.find_all('td')[3]
    cols44 = [ele.text.strip() for ele in cols44]
    data.append([ele for ele in cols44 if ele])

    cols55 = row.find_all('td')[5]
    cols55 = [ele.text.strip() for ele in cols55]
    data.append([ele for ele in cols55 if ele])


    print(cols11, cols22, cols33, cols44, cols55)


if(cols == cols11, cols2 == cols22, cols5 == cols55):
    print("no changes")
else:
    print("something has changed")

问题是:它总是说"no changes",即使我知道有些东西已经改变了。如何解决这个问题?

【问题讨论】:

  • 虽然它可能是相关的,但不是您问题的根源,您能用自己的话解释一下您希望条件if(cols == cols11, cols2 == cols22, cols5 == cols55) 适用的逻辑吗?与此相关的是,您是否手动检查了这些列表的内容以确保它们包含您期望的数据?
  • 好的,我试试。 colscols11 等是同一列。 colsX 包含第一次抓取的数据,colsXX 包含第二次抓取的数据。在 if 条件中,它比较“关联”列的内容。

标签: python html web-scraping beautifulsoup python-requests


【解决方案1】:

虽然可以通过这种方式比较列表,但尚不清楚您是如何得出结论,即您可以在 if 条件中使用逗号 , 代替逻辑 AND && 运算符。

您在这里所做的是将条件括在括号 () 中并用逗号 , 加入它们(似乎无意中)正在创建一个 tuple 结构;所有非空的tuples 评估为True。因此,您的脚本会不断地触及您认为只有在您的任何数据结构之间没有变化时才应该输入的逻辑分支。

相反,请按照您的意图正确使用逻辑 AND &&(并且不要将真值本身转换为元组):

if cols == cols11 && cols2 == cols22 && cols5 == cols55:
    print("no changes")
else:
    print("something has changed")

与您的问题的核心相切,但您的代码将受益于 (a) 以更具描述性的方式命名变量,以及 (b) 使用更适合您的用例的数据类型,而不是引入全新的每个索引的编号变量和不必要的重复代码。

【讨论】:

  • 已更改,非常感谢!
【解决方案2】:

除了其他人说的,你必须在暂停一段时间后再次向该 URL 发出 GET 请求,才能检测到网页数据的任何变化。

你正在做的是:

  1. 向 URL 发出 GET 请求
  2. 创建响应的soup 对象。
  3. soup 中提取数据并将它们存储在变量中。
  4. 暂停一会 - time.sleep(600)
  5. 再次从同一个 soup 中提取相同的信息 - (始终相等) 无需发出任何新的 GET 请求。

因此您需要在time.sleep(600) 语句之后添加此代码,以从网页(如果有)获取任何修改后的数据。

URL = "https://website.com"
website = requests.get(URL)
soup = BeautifulSoup(website.content, "html.parser")

table = soup.find("table", class_="table table-bordered table-sm table-responsive")
table_body = table.find('tbody')

rows = table_body.find_all('tr')

【讨论】:

  • 是的,就是这样。非常感谢你,你是英雄!
猜你喜欢
  • 2010-10-07
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多