Python爬虫:从后端分析为什么你爬虫爬取不到数据
仅仅是小编总结的三点而已,可能不是很全面,如果之后小编了解到新的知识点,可能还会增加的哈!
1. 最简单的爬虫代码
也就是各位最常使用的,直接利用requests模块访问当前网站链接,利用相关解析模块从而获取得到自己想要的数据,如下(利用python爬虫爬取自己csdn个人主页的简介数据):
# -*- coding: utf-8 -*-
import requests
from lxml import etree
url = 'https://blog.csdn.net/qq_45404396'
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.199.400 QQBrowser/11.8.5300.400'
}
rsp = requests.get(url=url,headers=headers)
html = etree.HTML(rsp.text)
info = html.xpath('//p[@class="introduction-fold default"]/text()')[0]
print(info)
运行结果:
下面展示它的后端实现,只是举个例子哈!利用SpringBoot+thymeleaf模拟哈!java代码和前端界面代码如下:
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.HashMap;
@Controller
public class TestController {
@GetMapping("/test1")
public String test1(Model model){
HashMap<String,Object> map = new HashMap<>();
map.put("name","liuze");
map.put("age",22);
model.addAttribute("data",map);
return "test1";
}
}
这里没有定义一个相关的实体类了,直接使用hashmap
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>test1</title>
</head>
<body>
<p th:text="${data.name}">
</p>
<p th:text="${data.age}"></p>
</body>
</html>
界面效果如下:
这两个数据你直接访问这个界面是可以获取得到的(如果部署到公网上去的话!),你可以直接去查看这个界面的源代码或者来到开发者工具下点击网络->全部下,找到当前界面的链接,点击,然后点击响应,如下:
通常可以通过上述这种方式判断你直接访问当前网页链接是否可以获取得到你想要的那些数据。
2. 需要到script标签去找数据
其实,也就是你想要的那个数据在一个script标签内,也就是说如果你在第1中情况下你没有找到你想要数据,这时候你可以去找找某个script标签下是否有你想要的数据。比如小编我想要获取我的csdn个人主页的各个勋章的名称,可以发现,在某个script标签下有你想要的数据,如下:
它的这个勋章实现效果我想应该是这样的,后端使用和方法1相同,只不过没有把相关数据写入到对应标签内,而是先把数据写到一个script标签内,然后利用编写js脚本加以展示。python代码抓取如下:
# -*- coding: utf-8 -*-
import requests
from lxml import etree
import json
url = 'https://blog.csdn.net/qq_45404396'
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.199.400 QQBrowser/11.8.5300.400'
}
rsp = requests.get(url=url,headers=headers)
html = etree.HTML(rsp.text)
info = html.xpath('//script/text()')[0]
index = info.find('=') + 1
_dict = json.loads(info[index:-1].strip())
_list = _dict['pageData']['data']['baseInfo']['medalModule']
count = 0
for e in _list:
print(e['name'], end=' ')
if count and count % 8 == 0:
print('\n')
count += 1
运行结果:
这种后端实现和上述一致,看看前端代码:
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>test1</title>
</head>
<body>
<p class="p1"></p>
<p class="p2"></p>
<script th:inline="javascript">
var data = [[${data}]];
document.querySelector('.p1').innerText = data.name;
document.querySelector('.p2').innerText = data.age;
</script>
</body>
</html>
运行结果:
3. 找ajax请求接口
如果通过上述两种方式,你还没有找到你想抓取的数据线索,你可以去看看网络->XHR(或JS)下有没有ajax链接接口了。比如我想抓取我的个人主页下的一些博客名称,这需要去找ajax链接接口了。
代码实现:
# -*- coding: utf-8 -*-
import requests
import json
url = 'https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=20&businessType=blog&orderby=&noMore=false&year=&month=&username=qq_45404396'
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.199.400 QQBrowser/11.8.5300.400'
}
rsp = requests.get(url=url,headers=headers)
_dict = json.loads(rsp.text)
_list = _dict['data']['list']
for e in _list:
print(e['title'])
运行结果:
这种后端实现如下:
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
@Controller
public class TestController {
@ResponseBody
@GetMapping("/test2")
public Map<String,Object> test1(Model model){
Map<String,Object> map = new HashMap<>();
map.put("name","liuze");
map.put("age",22);
return map;
}
@GetMapping("/test1")
public String test2(Model model){
return "test1";
}
}
前端代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>test1</title>
</head>
<body>
<p class="p1"></p>
<p class="p2"></p>
<script th:inline="javascript">
fetch('/test2',{
method:"get",
}).then(res=>{
return res.json();
}).then((res)=>{
document.querySelector('.p1').innerText = res.name;
document.querySelector('.p2').innerText = res.age;
});
</script>
</body>
</html>
运行结果:
之所以后面两种情况,直接访问当前页面链接你访问不到相关数据,我想和页面加载顺序是有一定关系的,当然,这个点我也不是很清楚,希望上述所讲能帮助到大家哈!