-前言
之前一直用scrapy与urllib姿势爬取数据,最近使用requests感觉还不错,这次希望通过对知乎数据的爬取为 各位爬虫爱好者和初学者更好的了解爬虫制作的准备过程以及requests请求方式的操作和相关问题。当然这是一个简单的爬虫项目,我会用重点介绍爬虫从开始制作的准备过程,目的是为了让和我一样自学的爬虫爱好者和初学者更多的了解爬虫工作。
一、观察目标网页模板和策略
很多人都忽略这一步,其实这一步最为重要,因为它决定了你将采取什么策略来获取数据,也可以评估出你能够做到什么程度
(1)打开浏览器的开发工具F12
这里我用的是Google浏览器,打开浏览器按F12,你将看到你加载网页情况,以及网络请求的方式和交互的参数情况。如果你没有看到,你应该百度自己的浏览器开发者工具,如何打开。我们在打开知乎门户网页后,F12看到开发者工具的Network一栏没有出现任何东西。如图1.1所示:
开发者工具 图 1.1
然后我们在知乎搜索框内输入需要搜索的内容,你将会看到网页后台与前台数据交互的变化,加载的数据以及数据请求的方式和参数。如图1.2:
服务端与浏览器交互的信息 图1.2
这里你可以看到有很多js文件和png格式文件,这些文件都是通过你的搜索这个动作,对方服务器返回的文件,根据这些你可以更加了解网页服务端与浏览器的交互过程。这里如果你很有经验的话,可以根据它的size和name字段快速找出你想要的交互文件。
因为我们之前的搜索操作,所以很容易可以看出来第一个带有search字段的是搜索操作时和网站服务器交互的文件。点击我们可以看到 如图1.3:
与服务器通信请求参数 图1.3
这里有返回给我们与服务器通信后的过程以及相关数据,右上方可以看到Headers、Previes、Response、cookie等选项 。
headers可以看到请求的参数,我们很多时候写爬虫访问服务器被拒绝就是因为这里有很多参数验证没有通过,所以学会运用这里的参数是很有必要的。Requests Headers 是你请求时所用的请求头,重要的是cookie与User-Agent,cookie可以让你免登陆,虽然有时效性,但是有时候会帮助你节省时间,同时它有时候也是网站监测你是否是爬虫的手段,userAgent基本都会被服务端检测,所以每次请求都需要带上。Query String Parameters是你请求时所带的参数,因为这里是get方式请求,所以这里的参数在你的请求链接是可以看到的。post请求时,这里的参数会很重要,每次请求都必需带上这些参数,比如账号登录,你就可以在这里看到账号和密码。
Previes 这个文件内容就是网站将会呈现给你的东西,也就是预览
Response 可以看到返回的数据文本,有时候这里可以直接看到json数据,解决动态页面时,如果你能够直接找到想要的数据,你可以很轻松的避开js文件,直接访问这个文件获取数据。
在知乎首页搜索后,你会发现没有换页,通过不停的下拉,会有新的数据产生。这里我们通过下拉时可以看到它产生了新的文件 如图 1.4:
下拉后变化 图1.4
多了一个search的请求文件,我们点开和第一个对比发现,offset字段从0变成了10。我们复制一下这里的url在新开的标签页粘贴后,发现如图1.5:
复制链接的页面 图1.5
看到返回的一个json类型的数据,这里中文都是unicode编码格式,所以我们需要自己写点代码,复制这些字符串,decode解码出中文。解码后你会发现,这些都是下拉时网页显示的数据。我们就可以通过正则表达式从这里将自己需要的数据提取出来,这里只是网页的第一层,为了进入第二层(点击一个链接,跳转的下一个页面),我们将提取这里所有的链接。
回顾我之前文章requests介绍用法,很容易写出:
#假设每个搜索项有500页,如果没有想要的内容,可以break
for i in range(500):
# key是要搜索的关键词
url = 'https://www.zhihu.com/r/search?q='+key+'&correction=1&type=content&offset='+str(i*10)
try: #try用在这里,后面会解释原因
response = requests.get(url,headers=headers)
except:
continue
response.encoding='unicode-escape'
page = lxml.html.fromstring(response.text)
hrefs = re.findall(rule,response.text)
好了第一层我们差不多做好了,进入网站第二层,随意点击一个我们搜索产生的内容标题,跳转至一个新的页面,我们用同样的方法,观察第二层我们与服务端交互的信息 如图 1.6:
当然你也可以添加这里面的js文件在代码中触发,但是这会变得很复杂,因为js文件作用很多,你要找到你想要的js文件并不容易。我们需要找到更快速有效的方法,这也是为什么“观察”是爬虫最重要的一环。
keys = ['.....'] #key 自己定义一个list
url = 'https://www.zhihu.com/r/search?q='+key+'&correction=1&type=content&offset='+str(i*10)
response = requests.get(url,headers=headers)
response.encoding='unicode-escape'
page = lxml.html.fromstring(response.text)