一、爬虫基本概念
1.1 爬虫定义
网络爬虫(又称网页蜘蛛,网络机器人)就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序。
只要是浏览器能做的事情,原则上,爬虫都能够做。
1.2 工作流程
- 搜索引擎流程:抓取网页—>数据存储—>预处理(如分词)—>提供检索服务让,网站排名(点击次数,被引用次数)
- 聚焦爬虫流程:url list—>响应内容(—>提取url—>url list)—>提取数据—>入库
聚焦爬虫流程需要根据一定的网页分析算法过滤与主题无关的网页,保存有用的连接并且添加到等待抓取得url对列中,并根据一定的搜索策略从等待队列中选择下一步要抓取的连接。重复着一个过程,直到满足一定条件为止。
1.3 通用搜索引擎的局限性
- 通用搜索引擎所返回的网页里90%的内容无用。
- 图片、音频、视频多媒体的内容通用搜索引擎无能为力。
- 不同用户搜索的目的不全相同,但是返回内容相同。
1.4 ROBOTS协议
网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取
例如:https://www.taobao.com/robots.txt
1.5 浏览器发送HTTP请求的过程
浏览器渲染出来的页面和爬虫请求的页面并不一样
爬虫要根据当前url地址对应的响应为准,当前url地址的elements的内容和url的响应不一样(js可能调整页面内容):
- 爬虫只会请求当前这个url,但不是请求js
- 浏览器拿到的内容,我们在浏览器中看到的内容时elements里面的内容
- elements=url对应的响应+js+css+图片
页面上的数据在?
- 当前url地址对应的响应中
- 其他的url地址对应的响应中(比如ajax请求)
- js生成的
- 部分数据在响应中
- 全部通过js生成
二、爬虫requests库
2.1 requests模块发送请求
1) requests模块如何发送请求:
response = requests.get(url)
判断请求是否是成功:
assert response.status_code == 200
response的常用方法:
- response.text # 返回的是一个 unicode 型的文本数据
- response.content # 返回的是 bytes 型的二进制数据
- response.status_code # 状态码
- response.request.headers # 请求头
- response.headers # 响应头
requests中解决编解码的方法:
- response.content.decode()
- response.content.decode("gbk")
- response.text
2) 发送带header的请求
模拟浏览器,欺骗服务器,获取和浏览器一致的内容
header的形式:字典
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
用法:
requests.get(url, headers=headers)
3) 发送带参数的请求
什么叫做请求参数:
例如:https://www.baidu.com/s?wd=python&c=b
参数的形式:字典
kw = {'wd': '长城'}
requests.get(url, params=kw) # url不需要有参数
# coding=utf-8
import requests
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
# p = {"wd": "传智播客"}
# url_temp = "https://www.baidu.com/s?"
# r = requests.get(url_temp, headers=headers, params=p)
# print(r.status_code)
# print(r.request.url)
url = "https://www.baidu.com/s?wd={}".format("传智播客") # 字符串格式化的另一种方式
r = requests.get(url, headers=headers)
print(r.status_code)
print(r.request.url)
url编码(%开头):
https://www.baidu.com/s?wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2
解码链接:http://tool.chinaz.com/tools/urlencode.aspx
贴吧爬虫实例:
# coding=utf-8
import requests
class TiebaSpider:
"""docstring for tiebaSpider"""
def __init__(self, tieba_name):
self.tieba_name = tieba_name
self.url_temp="https://tieba.baidu.com/f?kw="+tieba_name+"&ie=utf-8&pn={}"
self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
def get_url_list(self):
# url_list = []
# for i in range(10):
# url_list.append(self.url_temp.format(i*50))
# return url_list
return [self.url_temp.format(i*50) for i in range(10)]
def parse_url(self, url):
print(url)
response = requests.get(url, headers=self.headers)
return response.content.decode()
def save_html(self, html_str, page_num):
file_path = "{}——第{}页.html".format(self.tieba_name, page_num)
with open(file_path, "w", encoding="utf-8") as f: # 隐居-第一页.html
f.write(html_str)
def run(self): # 实现主要逻辑
# 1.构造url列表
url_list = self.get_url_list()
# 2.遍历,发送请求,获取相应
for url in url_list:
html_str = self.parse_url(url)
# 3.保存
page_num = url_list.index(url) + 1
# print(page_num)
self.save_html(html_str, page_num)
if __name__ == '__main__':
tieba_spider = TiebaSpider("隐居")
tieba_spider.run()