如何使用 Python scrapy 处理多个 URL
Posted
技术标签:
【中文标题】如何使用 Python scrapy 处理多个 URL【英文标题】:How to use Python scrapy for myltiple URL's 【发布时间】:2017-06-16 04:58:32 【问题描述】:我的问题与这篇文章类似:
How to use scrapy for Amazon.com links after "Next" Button?
我希望我的爬虫遍历所有“下一个”链接。我搜索了很多,但大多数人都专注于如何解析 ULR 或简单地将所有 URL 放在初始 URL 列表中。
到目前为止,我能够访问第一页并解析下一页的链接。但我不知道如何使用相同的爬虫(蜘蛛)访问该页面。我尝试将新 URL 附加到我的 URL 列表中,它确实附加了(我检查了长度),但后来它没有访问该链接。我不知道为什么...
请注意,就我而言,我只知道第一页的 URL。访问第一页后才能获取第二页的 URL。同样,第 (i+1)' 个页面的 URL 隐藏在第 i 个页面中。
在解析函数中,我可以解析并打印正确的下一页链接 URL。我只是不知道如何访问它。
请帮助我。谢谢!
import scrapy
from bs4 import BeautifulSoup
class RedditSpider(scrapy.Spider):
name = "test2"
allowed_domains = ["http://www.reddit.com"]
urls = ["https://www.reddit.com/r/LifeProTips/search?q=timestamp%3A1427232122..1437773560&sort=new&restrict_sr=on&syntax=cloudsearch"]
def start_requests(self):
for url in self.urls:
yield scrapy.Request(url, self.parse, meta=
'splash':
'endpoint': 'render.html',
'args': 'wait': 0.5
)
`
def parse(self, response):
page = response.url[-10:]
print(page)
filename = 'reddit-%s.html' % page
#parse html for next link
soup = BeautifulSoup(response.body, 'html.parser')
mydivs = soup.findAll("a", "rel" : "nofollow next" )
link = mydivs[0]['href']
print(link)
self.urls.append(link)
with open(filename, 'wb') as f:
f.write(response.body)
更新
感谢 Kaushik 的回答,我想出了如何让它发挥作用。虽然我仍然不知道为什么我最初添加新 URL 的想法不起作用...... 更新后的代码如下:
import scrapy
from bs4 import BeautifulSoup
class RedditSpider(scrapy.Spider):
name = "test2"
urls = ["https://www.reddit.com/r/LifeProTips/search?q=timestamp%3A1427232122..1437773560&sort=new&restrict_sr=on&syntax=cloudsearch"]
def start_requests(self):
for url in self.urls:
yield scrapy.Request(url, self.parse, meta=
'splash':
'endpoint': 'render.html',
'args': 'wait': 0.5
)
def parse(self, response):
page = response.url[-10:]
print(page)
filename = 'reddit-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
#parse html for next link
soup = BeautifulSoup(response.body, 'html.parser')
mydivs = soup.findAll("a", "rel" : "nofollow next" )
if len(mydivs) != 0:
link = mydivs[0]['href']
print(link)
#yield response.follow(link, callback=self.parse)
yield scrapy.Request(link, callback=self.parse)
【问题讨论】:
【参考方案1】:Scrapy docs 很好地解释了您的要求。我认为你不需要除此之外的任何其他解释。建议浏览一遍以便更好地理解。
不过先简单解释一下:
为了跟随链接到下一页,Scrapy 提供了许多方法。最基本的方法是使用http.Request方法
Request object : 类 scrapy.http.Request(url[, 回调, 方法='GET',标题,正文,cookies,元,编码='utf-8', priority=0, dont_filter=False, errback, flags])
>>> yield scrapy.Request(url, callback=self.next_parse)
url (string) – 这个请求的 URL
callback (callable) – 将调用此请求的响应(下载后)作为其第一个参数的函数。
为了方便起见,Scrapy 内置了使用 response.follow 创建 Request 对象的快捷方式,其中 url 可以是绝对路径或相对路径。
follow(url, callback=None, method='GET', headers=None, body=None, cookies=None,meta=None,编码=None,优先级=0,dont_filter=False, errback=无)
>>> yield response.follow(url, callback=self.next_parse)
如果您必须通过将值传递给 form 或任何其他类型的 input 字段来转到下一个链接,则可以使用 Form Request objects . FormRequest class 扩展了基本请求的功能 用于处理 HTML 表单。它使用 lxml.html 表单进行预填充 带有来自 Response 对象的表单数据的表单字段。
Form Request object from_response(response[, formname=None, formid=None, formnumber=0, formdata=None, formxpath=None, formcss=None, clickdata=None, dont_click=False, ...])
如果您想在您的蜘蛛中模拟 HTML 表单 POST 并发送几个键值字段,您可以返回一个 FormRequest 对象(来自您的蜘蛛),如下所示:
return [FormRequest(url="http://www.example.com/post/action",
formdata='name': 'John Doe', 'age': '27',
callback=self.after_post)]
注意:如果请求没有指定回调,将使用蜘蛛的 parse() 方法。如果在处理过程中引发异常,则会调用 errback。
【讨论】:
谢谢。有帮助! 当然,很高兴为您提供帮助!如果是您要找的,请将其标记为答案。以上是关于如何使用 Python scrapy 处理多个 URL的主要内容,如果未能解决你的问题,请参考以下文章
与Python Scrapy中的Selenium WebDriver并发