刮板抛出错误,同时从多个页面
我在Python编写的脚本保存的数据刮分布在多个页面从网页的某些产品的不同子分类链接,并保存在不同的表(将其命名为根据标题的产品)在Excel文件中。在这种情况下,我使用了“pyexcel”。首先,刮板应该将该网页中的“item_list”和“所有品牌”的名称进行比较。无论何时,找到匹配它会刮去该链接,然后追查和分析所有的子类别链接遍历多个页面,并保存在一个Excel文件,我在前面已经说。如果这些产品不分散在多个页面上,它将毫无错误地运行。但是,我在“item_list”中选择了三个已分页的“项目”。刮板抛出错误,同时从多个页面
当我执行我的脚本,它抛出下面的错误。但是,我注意到有了这个错误,一个包含来自单个页面的子类别链接的项目就被完成了。它会在保存子类链接下一页的数据时抛出错误。我该如何解决这个问题?提前致谢。
以下是完整的脚本:
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
你可能要绕一点发挥得到那个工作,但是如果你的数据集很大,它会更快一点。
看起来像你发现的问题。当我完成时回到你身边。谢谢Stael。 – SIM
你做了我的一天,男人!我可以问一个简单的问题吗? – SIM
是的,继续。 – Stael