1.1 指定URL
-
UA伪装
headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36' }
1.2 请求
-
请求参数
# get请求 params = { '参数': '值', } # post请求 data = { '参数': '值', }
-
get请求
response = requests.get(url=url, params=params, headers=headers)
-
post请求
response = requests.post(url=url, data=data, headers=headers)
-
关于字符编码
# 方法一:手动设定响应数据的编码格式 response.encoding = 'gbk' # 方法二:字符串统一编码(通用) str_name = str_name.encode('iso-8859-1').decode('gbk')
-
关于请求失败
def get_response(url): try: response = requests.get(url=url, headers=headers, timeout=30) if response.status_code == 200: return response except Exception: for i in range(1, 10): print(f'请求{url}超时,第{i}次重复请求') response = requests.get(url, headers=headers, timeout=30) if response.status_code == 200: return response
1.3 响应
-
响应类型
# 字符串 response.text # 二进制 response.content # json对象 json_obj = response.json() # json序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False json.dump(json_obj, fp=fp, ensure_ascii=False)
1.4 解析:正则、bs4、XPath
-
正则
page_text = requests.get(url=url, headers=headers).text ''' <div class="thumb"> <a href="/article/121721100" target="_blank"> <img src="//pic.qiushibaike.com/system/pictures/12172/121721100/medium/DNXDX9TZ8SDU6OK2.jpg" alt="指引我有前进的方向"> </a> </div> ''' ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>' # 如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。 # re.S:单行匹配,将整个字符串作为一个整体,在整体中进行匹配;让.匹配包括换行在内的所有字符 # re.M:多行匹配,将字符串按\n分开;让^匹配每行的开头,$匹配每行的结尾 re.findall(ex, page_text, re.S)
-
bs4
from bs4 import BeautifulSoup # 对象实例化:1.本地html文档 with open('./test.html','r',encoding='utf-8') as fp: soup = BeautifulSoup(fp,'lxml') # 对象实例化:2.互联网上获取的页面源码 page_text = response.text soup = BeatifulSoup(page_text,'lxml') # 方法和属性: soup.div # 首个div标签 soup.find('div') # 首个div标签 soup.find('div', class_='song') # 首个class='song'的div标签 soup.find_all('div') # 所有div标签(列表) # select选择器 soup.select('div') # 所有div标签(列表) soup.select('.tang>ul>li>a') # >表示一个层级 soup.select('.tang>ul a') # 空格表示多个层级 # 获取标签内文本数据 soup.a.text # 标签内所有文本 soup.a.get_text() # 标签内所有文本 soup.a.string # 标签下直系文本 # 获取标签中属性值 soup.a['href'] # a标签的href属性值
-
XPath
from lxml import etree # 对象实例化:1.本地html文档 html = etree.parse('./index.html', parser=etree.HTMLParser(encoding="utf-8")) html_text = etree.tostring(html) tree = etree.HTML(page_text) # 对象实例化:2.互联网上获取的页面源码 response = requests.get(url=url, params=params, headers=headers) html_text = response.text tree = etree.HTML(html_text) # /是一个层级,从根节点开始定位。 tree.xpath('/html/body/div') # //是多个层级,从任意位置开始定位。 tree.xpath('/html//div') tree.xpath('//div') # ./,从当前层级开始定位。 tree.xpath('./div') # 属性定位 tree.xpath('//div[@class="song"]') # 索引定位(索引从1开始) tree.xpath('//div[@class="song"]/p[3]') # 取文本:/text() 标签中直系文本 tree.xpath('//div[@class="tang"]//li[5]/a/text()') # 取文本://text() 标签中所有文本 tree.xpath('//li[7]//text()') tree.xpath('//div[@class="tang"]//text()') # 取属性:@attrName r = tree.xpath('//div[@class="song"]/img/@src') # xpath表达式 tree.xpath('//div[@class="bottom"]/ul/li/') # 热门城市a标签的层级关系 tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a') # 全部城市a标签的层级关系 # 全部城市a标签的层级关系 tree.xpath('//div[@class="bottom"]/ul/li/a | //div[@class="bottom"]/ul/div[2]/li/a')
1.5 存储
-
文本
page_text = response.text # 文本 with open('./a.txt', 'w', encoding='utf-8') as fp: fp.write(page_text)
-
图片
img_data = response.content # 二进制格式 with open('./qiutu.jpg','wb') as fp: fp.write(img_data)
-
json对象
list_data = response.json() # json对象 with open('./douban.json','w',encoding='utf-8') as fp: json.dump(list_data, fp=fp, ensure_ascii=False)