Scraper 在保存多个页面的数据时抛出错误

Scraper throws error while saving data from multiple pages

我在 python 中编写了一个脚本,用于从网页中抓取分布在多个页面上的某些产品的不同子类别 link,并将它们保存在不同的工作表中(根据excel 文件中的产品名称)。在这种情况下,我使用了 "pyexcel"。首先,爬虫应该比较该网页中 "item_list" 和 "All Brands" 的名称。每当找到匹配项时,它都会抓取 link 然后跟踪它并解析遍历多个页面的所有子类别 link 并将它们保存在 excel 文件中,正如我所说的多于。如果这些产品没有分布在多个页面上,它 运行s 没有任何错误。但是,我在 "item_list" 中选择了三个具有分页的 "items" 。

当我执行我的脚本时,它抛出以下错误。但是,我注意到由于出现该错误,单个页面中具有子类别 links 的项目已完成抓取。当从该子类别 links 的下一页保存数据时,它会抛出错误。我该如何解决这个问题?提前致谢。

这是完整的脚本:

import requests ; from lxml import html
from pyexcel_ods3 import save_data

core_link = "http://store.immediasys.com/brands/"
item_list = ['Adtran','Asus','Axis Communications']

def quotes_scraper(base_link, pro):

    response = requests.get(base_link)
    tree = html.fromstring(response.text)
    data = {}
    for titles in tree.cssselect(".SubBrandList a"):
        if titles.text == pro:
            link = titles.attrib['href']
            processing_docs(link, data)   #--------#Error thrown here#----- #

def processing_docs(link, data):

    response = requests.get(link).text
    root = html.fromstring(response)
    sheet_name = root.cssselect("#BrandContent h2")[0].text

    for item in root.cssselect(".ProductDetails"):
        pro_link = item.cssselect("a[class]")[0].attrib['href']
        data.setdefault(sheet_name, []).append([str(pro_link)])
    save_data("mth.ods", data)

    next_page = root.cssselect(".FloatRight a")[0].attrib['href'] if root.cssselect(".FloatRight a") else ""
    if next_page:
        processing_docs(next_page)

if __name__ == '__main__':
    for item in item_list:
        quotes_scraper(core_link , item)

我遇到的错误:

Traceback (most recent call last):
  File "C:\Users\ar\AppData\Local\Programs\Python\Python35-32\goog.py", line 34, in <module>
    quotes_scraper(core_link , item)
  File "C:\Users\ar\AppData\Local\Programs\Python\Python35-32\goog.py", line 15, in quotes_scraper
    processing_docs(link, data)
  File "C:\Users\ar\AppData\Local\Programs\Python\Python35-32\goog.py", line 30, in processing_docs
    processing_docs(next_page)
TypeError: processing_docs() missing 1 required positional argument: 'data'

顺便说一句,如果我 运行 这个脚本没有 "pyexcel",它根本不会遇到任何问题。我遇到的错误是因为写入和保存数据。

看着你的代码我想我能看到你的问题:

def processing_docs(link, data):

    response = requests.get(link).text
    root = html.fromstring(response)
    sheet_name = root.cssselect("#BrandContent h2")[0].text

    for item in root.cssselect(".ProductDetails"):
        pro_link = item.cssselect("a[class]")[0].attrib['href']
        data.setdefault(sheet_name, []).append([str(pro_link)])
    save_data("mth.ods", data)

    next_page = root.cssselect(".FloatRight a")[0].attrib['href'] if root.cssselect(".FloatRight a") else ""
    if next_page:
        processing_docs(next_page) # this line here!

您的函数 processing_docs 需要两个参数,但您递归调用它 (processing_docs(next_page)) 只有一个。我想你也想递归地将 data 字典传递给函数,以便你继续添加它? (虽然这可能是错误的 - 乍一看似乎它会保存第 1 页,然后保存第 1 和第 2 页,然后保存第 1、2 和 3 页..但我必须仔细观察才能确定)


关于你的第二个问题(在评论中),有几种方法可以做到这一点。

如果我理解你的代码,你正在使用 save_data("mth.ods", data) 保存你的数据 - 如果你将项目名称传递给 processing_docs 函数而不是这个:

def processing_docs(link, data, item):
    ....
    save_data(item + ".ods", data)

调用这个:

for titles in tree.cssselect(".SubBrandList a"):
    if titles.text == pro:
        link = titles.attrib['href']
        processing_docs(link, data, pro)

if next_page:
    processing_docs(next_page, data, item)

然后它将为每个项目生成一个新文件,并以该项目命名。


额外

你对递归的使用有点低效 - 我认为它会起作用,因为它会写 p1,然后写 p1 和 p2,然后写 p1-3,所以你最终会得到整个东西(除非数据中的东西正在被覆盖,但我不这么认为)。

如果您 不需要 需要转到下一页,那么只保存数据可能更好,例如

if next_page:
    processing_docs(next_page, data, item)
else:
    save_data(item + ".ods", data) # move here and take out elsewhere

您可能需要稍微尝试一下才能让它发挥作用,但如果您的数据集很大,它会更快一些。