1.Ajax是什么?
AJAX简单来说是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
常见的比如淘宝或者微博滑到底部会出现"点击加载更多",或者滑到底部会自动出现更多的内容。此类网站皆是Ajax网站
2.Ajax类型网站爬虫的特点
Ajax网站跟普通网站爬虫不同点在于Ajax是一种渲染的方式使数据呈现在页面之上,因此网页看到的内容跟我们requests请求网页的内容是不一样的
例如本次案例采用的网站:https://spa1.scrape.center/
import requests
response = requests.get(url = 'https://spa1.scrape.center/')
print(response.text)
这是最最基础的爬虫步骤,但请求结果与我们想要的结果明显不符。
3.查找Ajax接口
我们进入开发者模式--点击Network,这里看见所有的请求数据,而Ajax请求的类型是XHR的,因此我们点击Fetch/XHR接口类型,而下面status200的即为我们想要的数据
4.分析请求数据格式
得到Ajax接口数据之后,我们可以看到Ajax请求的格式,由此可以看出他们分页的情况仅是offset不同。
点击电影进入详情页后,又可以看出详情页的Ajax接口是根据ID区别出来的
至此我们的思路为,请求每一页的网站,得到每一页电影的ID。后续请求详情页地址的Ajax接口,之后分析即可
5.代码步骤
1.得到全部页面的数据
import requests
import re
import pymysql
import multiprocessing
index_url = 'https://spa1.scrape.center/api/movie/?limit=10&offset={offset}'
def scrapy_page(page):
url = index_url.format(offset = 10 * page)
return url
2.得到页面下的电影ID值
def scrapy_api(url):
id_list = []
response = requests.get(url = url)
json_text = response.json()
content = json_text['results']
for i in range(len(content)):
id_list.append(content[i]['id'])
return id_list
3.得到100部电影的详情页
def get_detail(id):
detail_url = f'https://spa1.scrape.center/api/movie/{id}/'
return detail_url
4.请求数据
def get_data(detail_url):
response = requests.get(url = detail_url)
html = response.json()
json_data = {
'name':html.get('name'),
'English_name': html.get('alias'),
'regions':html.get('regions'),
'categories':html.get('categories'),
'score':html.get('score'),
'drama':html.get('drama')
}
return json_data
5.数据保存(这里我保存到了mysql中)
def save_data(json_data):
regions = ', '.join(json_data.get('regions'))
categories = ', '.join(json_data.get('categories'))
sql = "INSERT INTO Ajax_test1 (name, English_name, regions, categories, score, drama) VALUES (%s, %s, %s, %s, %s, %s)"
values = (
json_data.get('name'),
json_data.get('English_name'),
regions,
categories,
json_data.get('score'),
json_data.get('drama')
)
cursor.execute(sql, values)
conn.commit()
完整代码
import requests
import re
import pymysql
import multiprocessing
index_url = 'https://spa1.scrape.center/api/movie/?limit=10&offset={offset}'
conn = pymysql.connect(host='localhost',user='root',password='123456',port=3306)
cursor = conn.cursor()
cursor.execute("USE test")
def scrapy_api(url):
id_list = []
response = requests.get(url = url)
json_text = response.json()
content = json_text['results']
for i in range(len(content)):
id_list.append(content[i]['id'])
return id_list
def scrapy_page(page):
url = index_url.format(offset = 10 * page)
return url
def get_detail(id):
detail_url = f'https://spa1.scrape.center/api/movie/{id}/'
return detail_url
def get_data(detail_url):
response = requests.get(url = detail_url)
html = response.json()
json_data = {
'name':html.get('name'),
'English_name': html.get('alias'),
'regions':html.get('regions'),
'categories':html.get('categories'),
'score':html.get('score'),
'drama':html.get('drama')
}
return json_data
def save_data(json_data):
regions = ', '.join(json_data.get('regions'))
categories = ', '.join(json_data.get('categories'))
sql = "INSERT INTO Ajax_test1 (name, English_name, regions, categories, score, drama) VALUES (%s, %s, %s, %s, %s, %s)"
values = (
json_data.get('name'),
json_data.get('English_name'),
regions,
categories,
json_data.get('score'),
json_data.get('drama')
)
cursor.execute(sql, values)
conn.commit()
def main():
for page in range(10):
url = scrapy_page(page)
id_lists = scrapy_api(url)
for id in id_lists:
detail_url = get_detail(id)
json_data = get_data(detail_url)
save_data(json_data)
print(f'完成了第{id}份')
if __name__ == '__main__':
main()