【1】Linux sudo pip3 install requests 【2】Windows python -m pip install requests
requests.get()
【1】作用 向目标网站发起请求,并获取响应对象 【2】参数 2.1> url :需要抓取的URL地址 2.2> headers : 请求头 2.3> timeout : 超时时间,超过时间会抛出异常
爬虫程序示例
import requests resp = requests.get(url='https://www.jd.com/') # text属性:获取响应内容-字符串(右键->查看网页源代码) html = resp.text # content属性:获取响应内容-bytes(抓取图片、文件、音频、视频...) html = resp.content # status_code属性:获取HTTP响应码 code = resp.status_code # url属性:返回实际数据的URL地址 url = resp.url print(url)
响应对象(resp)属性
【1】text :拿到网页源代码字符串 【2】resp.json() :拿到json格式的数据(响应数据为json格式的) 【3】content :字节流 【4】status_code :HTTP响应码 【5】url :实际数据的URL地址 【6】encoding :用法--res.encoding = 'utf-8' 改变字符编码 【7】apparent_encoding 可有获取现有的字符编码格式 【8】resp.headers :获取请求头 【9】resp.cookies :获取cookies
重大问题思考
==网站如何来判定是人类正常访问还是爬虫程序访问?--检查请求头(User-Agent,Cookies,签名验证)
# 请求头(headers)中的 User-Agent # 测试案例: 向测试网站http://httpbin.org/get发请求,查看请求头(User-Agent) import requests url = 'http://httpbin.org/get' headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'} html = requests.get(url=url,headers=headers).text print(html) # 请求头中:User-Agent为-> python-requests/2.22.0 那第一个被网站干掉的是谁???我们是不是需要发送请求时重构一下User-Agent???添加 headers 参数!!!
重大问题解决 - headers参数
""" 包装好请求头后,向测试网站发请求,并验证 养成好习惯,发送请求携带请求头,重构User-Agent """ import requests url = 'http://httpbin.org/get' headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1'} html = requests.get(url=url,headers=headers).text # 在html中确认User-Agent print(html)
【1】字符串相加 【2】字符串格式化(占位符 %s) 【3】format()方法 'http://www.baidu.com/s?{}'.format(params) url = 'https://www.guazi.com/dachang/buy/o{}/#bread' for i in range(1, 21): page_url = url.format(i) print(page_url)
r_list=re.findall('正则表达式',html,re.S)
元字符 | 含义 |
---|---|
. | 任意一个字符(不包括\n) |
\d | 一个数字 |
\s | 空白字符 |
\S | 非空白字符 |
[] | 包含[]内容 |
* | 出现0次或多次 |
+ | 出现1次或多次 |
思考 - 匹配任意一个字符的正则表达式?
r_list = re.findall('.', html, re.S)
贪婪匹配(默认)
1、在整个表达式匹配成功的前提下,尽可能多的匹配 * + ? 2、表示方式:.* .+ .?
非贪婪匹配
1、在整个表达式匹配成功的前提下,尽可能少的匹配 * + ? 2、表示方式:.*? .+? .??
代码示例
import re html = ''' <div><p>九霄龙吟惊天变</p></div> <div><p>风云际会潜水游</p></div> ''' # 贪婪匹配 p = re.compile('<div><p>.*</p></div>',re.S) r_list = p.findall(html) print(r_list) # 非贪婪匹配 p = re.compile('<div><p>.*?</p></div>',re.S) r_list = p.findall(html) print(r_list)
作用
在完整的模式中定义子模式,将每个圆括号中子模式匹配出来的结果提取出来
分组总结
1、在网页中,想要什么内容,就加() 2、先按整体正则匹配,然后再提取分组()中的内容 如果有2个及以上分组(),则结果中以元组形式显示 [(),(),()] 3、最终结果有3种情况 情况1:[] 情况2:['', '', ''] -- 正则中1个分组时 情况3:[(), (), ()] -- 正则中多个分组时
【1】官网地址:https://maoyan.com/board/4 【2】爬取目标 top100电影中100个电影的 2.1》电影名称 2.2》电影主演 2.3》上映时间
【1】查看网页源码,确认数据来源 响应内容中存在所需抓取数据 - 电影名称、主演、上映时间 【2】翻页寻找URL地址规律 第1页:https://maoyan.com/board/4?offset=0 第2页:https://maoyan.com/board/4?offset=10 第n页:offset=(n-1)*10 【3】编写正则表达式 '<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>' 【4】开干吧兄弟
"" 猫眼电影top100抓取 """ import requests import re import time import random class MaoYanSpider: def __init__(self): self.url = 'https://maoyan.com/board/4?offset={}' self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'} def get_html(self, url): """请求""" html = requests.get(url=url, headers=self.headers).text # 调用解析函数 self.parse_html(html) def parse_html(self, html): """正则解析提取数据""" regex = '<div class="movie-item-info">.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?<p class="releasetime">(.*?)</p>' # [('名称','主演','时间'),(),...] r_list = re.findall(regex, html, re.S) for r in r_list: print(r) def crawl(self): for offset in range(0, 91, 10): page_url = self.url.format(offset) self.get_html(url=page_url) # 控制频率 time.sleep(random.randint(1, 3)) if __name__ == '__main__': spider = MaoYanSpider() spider.crawl()