豆瓣网的数据都是通过ajax异步加载上去的,所以我们按照xpath的方式提取数据是提取不完整的
第一步:确定爬取的URL并找到参数规律
1.进入到爬取的目标界面
进入到豆瓣网,点击分类,会显示出下图的界面
2.找到Ajax的请求信息
打开chrome的开发者工具刷新下界面
选中Network→XHR,然后就会看到ajax请求的url和参数了
3.分析数据结构
双击上面的路径,会看到json数据的内容(图1)
把数据复制出来,格式化以后,可以看到data列表里面存放多个字典结构的数据
图1.
图2.
4.分析url和参数
当我们点击不同的标签(图1),url会发生变化(图2)
这里可以看出各个参数对应的参数值
sort和range是默认值,可以不填写
tags是传入电影形式和特色
start是开始的位置,相当与分页
genres是电影的类型
countries是地区
year_range是年限的范围
图1.点击不同的标签
图2.
第二步:生成框架
这个跳过了,不会的可以看我Scrapy系列的文章
第三步:编写代码
1.封装数据
2.设置ROBOTSTXT_OBEY为False
这步很重要,豆瓣网不允许爬虫爬取的,所以把ROBOTSTXT_OBEY设置为False,表示当爬取内容不符合该协议且仍要爬取时
3.编写代码
这个逻辑很简单,主要部分是parse函数
#coding:utf-8
from scrapy import Request
from scrapy.spiders import Spider
from douban.items import DoubanItem
import json
class DoubanSpider(Spider):
name = 'douban'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36"}
current_page = 0 # 当前页
def start_requests(self):
url = self.generateURL(0)
yield Request(url,headers=self.headers)
def parse(self, response):
json_text = response.text
movie_dict = json.loads(json_text)
if len(movie_dict) == 0:
return
else:
item = DoubanItem()
for one_movie in movie_dict["data"]:
item["title"] = one_movie["title"]
item["directors"] = one_movie["directors"]
item["casts"] = one_movie["casts"]
item["rate"] = one_movie["rate"]
yield item
#自动翻页
self.current_page+=1
url = self.generateURL(self.current_page)
yield Request(url,headers=self.headers)
#生成url
def generateURL(self,current_page):
form = "电影" # 形式
feature = "" # 特色
type = "剧情" # 类型
countries = "美国" # 地区
start_year = "2000" # 开始年限
end_year = "2020" # 截至年限
# form = "" # 形式
# feature = "" # 特色
# type = "" # 类型
# countries = "" # 地区
# start_year = "" # 开始年限
# end_year = "" # 截至年限
url="https://movie.douban.com/j/new_search_subjects?tags="
if form != "" and form != None:
url = url + form + ","
if feature != "" and feature != None:
url = url + feature + ","
else:
url = url[:-1]#如果feature为空则把最后一个逗号去掉
url = url + "&start=" + str(current_page * 20)
if type != "" and type != None:
url = url + "&genres=" + type
if countries != "" and countries != None:
url = url + "&countries=" + countries
if start_year != "" and start_year != None and end_year != "" and end_year != None :
url = url + "&year_range=" + start_year + "," + end_year
return url
总结:
爬取动态网页的代码实现比较简单,难在分析url上,要经过多次测试才能把url分析出来