爬虫知识点(一)
requests模块的编码流程:
指定url
发起请求post/get( url header paramas/data/json proxies)
获取响应数据(爬取到的数据)text json() content
持久化存储
get方法的参数:
url
params
headers
get方法的返回值:
response
response的属性:
text:字符串形式的响应数据
当我们对一个陌生的网站进行指定数据爬取之前,我们在写代码之前必须要做的一个事情就是校验你想要爬取的数据是否为动态加载的数据
是动态加载的数据
基于抓包工具进行全局搜索,锁定动态加载数据对应的数据包即可。从数据包中提取请求的url和请求方式和请求参数。
不是动态加载的数据
直接对地址栏的url发起请求就可以获取指定数据
cookie
Session对象。
Session对象的创建:requests.Session()
对象的作用:
可以跟requests一样调用get/post进行请求的发送。在使用session进行请求发送的过程中,如果产生了cookie,则cookie会被自动存储到session对象中。
在爬虫中使用session处理cookie时,session对象至少需要被用几次?
两次。第一次是为了捕获和存储cookie到session对象中,第二次就是用携带cookie的session进行请求发送,这次请求发送就是携带cookie发起的请求。
数据解析
正则
bs4
xpath(重点)
pip install bs4
pip install lxml
bs4
标签定位
soup.tagName:返回第一次出现的tagName标签
属性定位:soup.find('tagName',attrName='value')
findAll和find的用法一样,但是返回值不一样
选择器定位:
select('selector')
数据的提取
提取标签中存在的数据
.string:取出标签直系的文本内容
.text:取出标签中所有的文本内容
提取标签属性中存储的数据
tagName['attrName']
xpath表达式
标签定位
最左侧的/:必须要从根标签开始逐层的定位目标标签
非最最侧的/:表示一个层级
最左侧的//:可以从任意位置定义目标标签
非最左侧的//:表示多个层级
属性定位://tagName[@attrName='value']
索引定位://tagName[index],index索引是从1开始
模糊匹配:
//div[contains(@class, "ng")] 定位到class属性值中包含ng的div标签
//div[starts-with(@class, "ta")] 定位到class属性值中是以ta开头的div标签
数据提取
取标签中的数据
/text():直系文本内容
//text():所有的文本内容
去属性的数据
tagName/@attrName
#常用语句 #requests import requests #url url = 'https://www.sogou.com/' #header headers = { "User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36' } #paramas params = { "type": "17", "interval_id": "100:90", "action": "", "start": "20", "limit": "10", } #data data = { "cname": "", "pid": "", "keyword": "北京", "pageIndex": "1", "pageSize": "10", } #response #get response = requests.get(url=url,params=params,headers=headers) response.encoding = 'utf-8' page_text = response.text #post response = requests.post(url=url,headers=headers,data=data) page_text = response.json() for dic in page_text['Table1']: pos = dic['addressDetail'] print(pos) #cookie #基于session自动处理cookie sess = requests.Session() sess.get(url='https://xueqiu.com/',headers=headers) url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=20367942&count=15&category=-1' json_data = sess.get(url=url,headers=headers).json() json_data #代理操作 #代理精灵:http://http.zhiliandaili.cn/ #1.构建一个代理池 ips_list = [] url = 'http://t.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=52&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2' page_text = requests.get(url=url,headers=headers).text tree = etree.HTML(page_text) ip_list = tree.xpath('//body//text()') for ip in ip_list: dic = {'https':ip} ips_list.append(dic) ips_list import random #使用代理池操作 url = 'https://www.xicidaili.com/nn/%d' all_data = [] for page in range(1,30): new_url = format(url%page) #proxies={'http':'ip:port'} page_text = requests.get(url=new_url,headers=headers,proxies=random.choice(ips_list)).text tree = etree.HTML(page_text) #在xpath表达式中不可以出现tbody标签,否则会出问题 tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:] for tr in tr_list: ip_addr = tr.xpath('./td[2]/text()')[0] all_data.append(ip_addr) print(len(all_data)) #bs4 from bs4 import BeautifulSoup #bs4中有哪些方法和属性可以被我们使用 fp = open('./test.html','r') soup = BeautifulSoup(fp,'lxml') #标签的定位 soup.div #属性定位:根据属性定位具体的标签 soup.find('div',class_='song')#class属性为song的div标签 soup.find('a',id='feng') soup.findAll('a',id='feng') soup.select('#feng')#根据id选择器定位a标签 soup.select('.song')#定位class为song的标签 #层级选择器 soup.select('.tang > ul > li > a') # >表示一个层级 soup.select('.tang a') #空格表示多个层级 soup.p.string soup.div.text soup.a['href'] #xpath解析 from lxml import etree tree = etree.parse('./test.html')#将本地存储的html文档进行解析 tree.xpath('/html/head')#从根标签开始定位head标签 tree.xpath('//head') #将html文档中所有的head标签定位到 tree.xpath('/html//meta') #定位class为song的div标签 tree.xpath('//div[@class="song"]') tree.xpath('//li[1]') tree.xpath('//a[@id="feng"]/text()') tree.xpath('//div[@class="song"]//text()') tree.xpath('//a[@id="feng"]/@href') tree = etree.HTML(page_text)