python - 用 scrapy 抓取无限滚动的网站
问题描述
我想用 scrapy从网站https://www.seekingalpha.com抓取收入通话记录。
蜘蛛应该表现如下: 1) 在开始时ccodes
提供公司代码列表。2) 对于每家公司,所有可用的成绩单网址均从https://www.seekingalpha.com/symbol/A/earnings/transcripts解析。3) 从每个成绩单 url 解析相关内容。
困难在于https://www.seekingalpha.com/symbol/A/earnings/transcripts包含无限滚动机制。因此,我们的想法是单独遍历 json 文件https://www.seekingalpha.com/symbol/A/earnings/more_transcripts?page=1由page=1,2,3..
javascript 调用。json 文件包含键html
和count
. html
应该使用密钥来解析脚本 url,count
当没有更多的 url 时,应该使用密钥来停止。其标准是count=0
。
到目前为止,这是我的代码。我已经成功地解析了每个公司代码的第一个 json 页面。但我不知道如何遍历 json 文件并在没有更多 url 时停止。
import scrapy
import re
import json
from scrapy.http import FormRequest
from scrapy.selector import Selector
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = ["https://seekingalpha.com/account/login"]
custom_settings = { 'DOWNLOAD_DELAY': 2 }
loginData = {
'slugs[]': "",
'rt': "",
'user[url_source]': 'https://seekingalpha.com/account/login',
'user[location_source]': 'orthodox_login',
'user[email]': 'abc',
'user[password]': 'xyz'
}
def parse(self, response):
return scrapy.FormRequest.from_response(
response = response,
formdata = self.loginData,
formid = 'orthodox_login',
callback = self.verify_login
)
def verify_login(self, response):
pass
return self.make_initial_requests()
def make_initial_requests(self):
ccodes = ["A", "AB", "GOOGL"]
for ccode in ccodes:
yield scrapy.Request(
url = "https://seekingalpha.com/symbol/"+ccode+"/earnings/more_transcripts?page=1",
callback = self.parse_link_page,
meta = {"ccode": ccode, "page": 1}
)
def parse_link_page(self, response):
ccode = response.meta.get("ccode")
page = response.meta.get("page")
data = json.loads(response.text)
condition = "//a[contains(text(),'Results - Earnings Call Transcript')]/@href"
transcript_urls = Selector(text=data["html"]).xpath(condition).getall()
for transcript_url in transcript_urls:
yield scrapy.Request(
url = "https://seekingalpha.com"+transcript_url,
callback = self.save_contents,
meta = {"ccode": ccode}
)
def save_contents(self, response):
pass
您应该能够在没有身份验证的情况下执行代码。预期的结果是抓取来自https://www.seekingalpha.com/symbol/A/earnings/transcripts的所有 url 。因此有必要访问https://www.seekingalpha.com/symbol/A/earnings/more_transcripts?page=page直到page = 1,2,3..
所有可用的 url 被解析。
解决方案
在遍历 transcript_urls 后添加以下内容似乎可行。如果在当前页面上找到了 transcript_urls,它会产生一个新的请求,并回调 parse_link_page。
if transcript_urls:
next_page = page + 1
parsed_url = urlparse(response.url)
new_query = urlencode({"page": next_page})
next_url = urlunparse(parsed_url._replace(query=new_query))
yield scrapy.Request(
url=next_url,
callback=self.parse_link_page,
meta={"ccode": ccode, "page": next_page},
)
推荐阅读
- elasticsearch - 显示和更改参数 threadpool.bulk.queue_size
- typescript - 打字稿:“从不”类型上不存在属性“标题”
- reactjs - 无法从登录重定向到仪表板
- php - 如何从网址中删除“公共”
- c# - “SelectedItem”组合框属性
- react-native - 动态设置 Apollo 客户端标头不起作用
- javascript - jQuery单击并在一个功能中加载
- python-3.x - 无法从 OpenGL_accelerate 加载 numpy_formathandler 加速器
- spring - 值对象为 @AggregateIdentifier 和 @TargetAggregateIdentifier
- spring - Spring Cloud Contract - 字符串数组作为查询参数