python-3.x - 使用递归进行网络抓取 - 将返回函数放在哪里
问题描述
我正在尝试抓取一个网站以获取文本。每个页面都包含一个到下一页的链接,即第一页有链接“/chapter1/page2.html”,其中有链接“/chapter1/page3.html” 最后一页没有链接。我正在尝试编写一个访问 url、打印页面文本、搜索文本并找到下一页的 url 并循环直到没有 url 的最后一页的程序。我尝试使用 if、else 和 return 函数,但我不明白我需要把它放在哪里。
def scrapy(url):
result = requests.get(url, timeout=30.0)
result.encoding = 'cp1251'
page = result.text
link = re.findall(r"\bh(.+?)html", page) # finds link to next page between tags
print("Continue parsing next page!")
url = link
print(url)
return(url)
url = "http://mywebpage.com/chapter1/page1.html"
result = requests.get(url, timeout=30.0)
result.encoding = 'cp1251'
page = result.text
link = re.findall(r"\bh(.+?)html", page)
if link == -1:
print("No url!")
else:
scrapy(url)
不幸的是,它不起作用;它只做一个循环。你能告诉我我做错了什么吗?
解决方案
有几件事:为了递归,scrapy 需要调用自己。其次,递归函数需要针对基本案例和递归案例的分支逻辑。换句话说,您需要部分函数看起来像这样(伪代码):
if allDone
return
else
recursiveFunction(argument)
对于scrapy,您需要在找到链接的行下方(您调用re.findall 的行)下面的这个分支逻辑。如果你没有找到链接,那么scrapy就完成了。如果你找到一个链接,那么你再次调用scrapy,传递你新找到的链接。你的 scrapy 函数可能需要更多的小修复,但希望这会让你摆脱递归的束缚。
如果你想真正擅长递归思考,这本书是一本好书:https ://www.amazon.com/Little-Schemer-Daniel-P-Friedman/dp/0262560992
推荐阅读
- python-2.7 - SyntaxError:使用管道的无效语法。引用
- c# - 使用 ASP.NET Core 2.2 写入文件的 Log4Net
- angular - 当 Angular 路由器防护 canActivate 在路由更改时返回 no 时,“无法读取未定义的属性 'nodeName'”
- excel - 根据 2 个不同的范围减去不同工作表中的单元格
- javascript - 如何在 setState 中进行验证?
- r - 我的 DLL 在 RStudio 中无法按预期工作
- cmake - Eclipse CDT 和 CMake + Ninja——适当的项目组织
- reactjs - 是否可以在 reactJs 应用程序中使用 iframe 元素打开存储在本地存储中的 html 页面?
- jquery - 带有片段的 Ecto 查询
- objective-c - 如何使子类符合 Objective-C 中的协议?