引言
现在大多数网站都采用了动态加载方式来展现其内容,本篇文章我们就来演示如何抓取动态加载的网站内容。
需求分析
爬取卡车之家新闻频道所有新闻内容。(http://www.360che.com/news/)
网站分析
首先,我们打开目标网页,可发现网页中展示了新闻列表,当我们向下滑动网页时,可以看到网页有加载的过程,加载完成后会展现出新的新闻列表。
如果我们使用requests对URL进行访问,打印其response,可以发现,列表返回的内容为加载之前的内容,是不全的,那么我们要如何才能获取到全部的新闻内容呢?
这里我们需要借助一个工具——charles。 charles是一个接口分析工具,可以帮助我们查看接口的调用。
首先我们打开charles,然后再次打开目标网页,可以看到charles中显示了当前调用的接口。
我们下拉网页至底部,继续观察charles中的显示。可以看到charles中新增了两个接口的调用。
将网页内容翻至第二页、第三页,同样下拉到最下方,观察charles中的记录。
通过观察分析可以看到,每一个网页除了调用pager的网页之外,下拉加载的地址为http://www.360che.com/ajaxpage/ArticleCategory2014/ArticleCategory2014Ajax.aspx?c=1&p=2。第一页加载2、3,第二页加载5、6,第三页加载8、9。 我们将最后的数字改为1、4、7时,可以发现返回结果中的新闻内容与pager相对应。
此时我们可以确认通过访问 http://www.360che.com/ajaxpage/ArticleCategory2014/ArticleCategory2014Ajax.aspx?c=1&p=1,改变最后一位的数字,就可以访问到全部的新闻内容。
确定了如何遍历网页内容后,我们需要确定如何结束循环遍历。通常的网站,当我们访问一个较大的或者不存在的链接时,会返回错误,今天的目标网站不一样,我们将最后一个数字改成10000.可以看到还是有返回结果。当把数字改成20000时,也是有返回结果的。不过,仔细观察两次的返回结果,可以发现这两次的返回结果都是一样的。所以我们结束的判断为当前接口返回的内容和上一次调用接口返回的内容一致,就结束访问。
找到了开始和结束的确认方式,我们再在当前的基础上增加将新闻url存储到redis数据库的过程,方便通过scrapy-redis进行新闻网页的下载。
部分代码
以下是主端代码。
import requests
from bs4 import BeautifulSoup
import redis
class Item():
def __init__(self,title,url,time,auth):
self.title = title
self.url = url
self.time = time
self.auth = auth
def save(self):
r = redis.Redis()
r.rpush('360che', self.url)
# print(self.url)
def parse(text):
soup = BeautifulSoup(text,'html.parser')
try:
page_list = soup.find_all("div",class_='probox_1')
for page in page_list:
title = page.find(class_='news_dk1').get_text()
url = page.find(class_='news_dk1').find('a')['href']
time = page.find(class_='news_dk3a ft').get_text()[:11]
auth = page.find(class_='news_dk3a ft').get_text()[11:]
item = Item(title,url,time,auth)
item.save()
except Exception as e:
print(e)
if __name__ == "__main__":
flag = None
base_url = 'http://www.360che.com/ajaxpage/ArticleCategory2014/ArticleCategory2014Ajax.aspx?c=1&p='
page = 1
while requests.get(base_url+str(page)).text != flag:
flag = requests.get(base_url+str(page)).text
print("第%s页爬取完成"%page)
page += 1
parse(flag)
print("共爬取%s页数据"%page)
print("Work done!")
源码
链接:https://pan.baidu.com/s/1nVb4OG2GSwAx5ZKB_d3gQg 密码:plrw
Python软件开发测试交友群QQ:952490269(加群备注software),欢迎加入!