一、明确爬取任务目标
由于我只知道新浪财经这一家财经类网站,所以决定爬取新浪财经网。爬取大概分为两层。第一层爬取各个股票的简略财经信息,并顺便获取相应公司的链接;第二层就利用上一层爬到的公司链接,爬取各个公司的年度报告。
我在第一层爬取到的信息类似于下面这样:
['600696', 'ST岩石', '2019-07-10', '0.02', '7435.61', '12.14', '738.57', '-46.04', '0.00', '2.46', '0.00', '26.87', '不分配', '明细', '--']
根据爬取到的股票id,可以生成第二层爬取的url。不过这个url并不是最终年度报告pdf资源的url,要获取这个链接还需要进一步的爬取。
二、selenium、requests优劣分析
selenium | requests | |
---|---|---|
爬取速度 | 较慢 | 较快 |
实现登录操作 | 容易 | 需要考虑一系列问题,很麻烦 |
页面中含有js代码生成元素 | 可以直接获取元素 | 很麻烦 |
如果网站有反爬虫机制 | 较容易避开 | 很麻烦 |
需要说明一下,有很多网站都会对用户的访问进行限速,当然也就限制了爬虫的速度,所以在实际爬取的时候selenium并不比requests慢很多。
三、“踩点”
到新浪官网首页,选择“财报查询”,可以看到想要的股票列表。【相关链接】分析html文本,可以发现tbody中的每个tr标签,都对应一行股票信息。
点击股票名称,可以进入相应公司的页面。然后,点击“公司咨询”>“年度报告”就可以看到公司的年度报告啦。
同样,可以知道年度报告的链接都在class=datelist的div标签下。
大概知道了这些信息后,就可以开始编写代码爬取信息啦。
四、代码实现
1、解析股票列表
parse_page实现了对股票列表html的解析。tbody > tr对应列表中的一行,而tr > td 则对应了每一行的各个信息。items是一个生成器,从中可以获取所有行。contents也是一个生成器,可以获取每一列。按照这样的方法解析股票简略信息。
def parse_page(self):
self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#box > table > tbody")))
html = self.browser.page_source
doc = pq(html)
items = doc("#box > table > tbody > tr").items()
for item in items:
# 从上到下爬取,最后一个item为页面链接
if item('td').attr('id') != 'pages':
info_list = []
# href为详细信息链接
href