只有代码示例的总结,理论性知识偏少
一:urllib2模块的使用
- 话不多说直接代码
1.通过一个小demo了解urllib2第一步
# -*- coding:utf-8 -*-
#添加注释,让python源代码支持中文
#引入模块
import urllib2
#访问目标网站,获取响应数据
response = urllib2.urlopen('https://www.taobao.com')
#打印数据
print response.read()
#将数据写入文档中
with open('1.html', 'w') as f:
f.write(response)
2.请求操作
# -*- coding:utf-8 -*-
import urllib2
import random
#定义可用的user_agent
ua = [ 'Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50' 'Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0' 'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)' 'Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)' 'User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)' ]
#随机获取一个user_agent
user_agent = random.choice(ua)
#定义请求头
my_headers = { 'User-agent':user_agent, 'message':'我是spider哈哈哈哈哈' }
#分装请求对象,并且设置请求头数据
url = 'https://www.taobao.com'
request = urllib2.Request(url, headers=my_headers)
#发送请求并且获得数据
response = urllib2.urlopen(request)
print (response.read())
3.get/post请求
get请求
import urllib2
import urllib
import random
ua = [
'Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50'
'Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0'
'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)'
'Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)'
'User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)'
]
#随机取一个ua作为身份标示
user_agent = random.choice(ua)
#定义传输的数据
keyw = raw_input('请输入关键词:')
get_param = {
'wd':keyw
}
#重新编码
data = urllib.urlencode(get_param)
#定义url地址
url = 'https://www.baidu.com/s?'
final_url = url + data
print(final_url)
#封装请求对象
request = urllib2.Request(final_url)
request.add_header('User-agent', user_agent)
#发送请求的得到相应的数据
response = urllib2.urlopen(request)
print(response.read())
************************************************************
post请求
import urllib2
import urllib
import random
import hashlib
import time
E = 'fanyideskweb'
#salt盐值
r = str(time.time()*1000 + random.randint(1,10))
#确定翻译的数据
n = raw_input('请输入翻译内容:')
#确定加密混淆
O = 'aNPG!!u6sesA>hBAW1@(-'
#确定sign参数
sing = hashlib.md5(E + n + r + O).hexdigest()
headers = {
"Referer": "http://fanyi.youdao.com/",
"Cookie":'OUTFOX_SEARCH_USER_ID_NCOO=2075764580.1728754; OUTFOX_SEARCH_USER_ID=-995280811@10.168.8.63; JSESSIONID=aaaxakcpWa-oo8wK72ydw; fanyi-ad-id=39535; fanyi-ad-closed=1; ___rl__test__cookies=1515468614442i=hell&from=AUTO&to=AUTO&smartresult=dict&client=fanyideskweb&salt=1515468614446&sign=710df1dcc70f91c1b04e795a34704c8e&doctype=json&version=2.1&keyfrom=fanyi.web&action=FY_BY_REALTIME&typoResult=false'
}
ua = [
'Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50'
'Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0'
'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)'
'Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)'
'User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)'
]
user_agent = random.choice(ua)
url = 'http://fanyi.youdao.com/ctlog?pos=undefined&action=&sentence_number=1&type=zh-CHS2en '
form_data = {
'i' :'n',
'from': 'AUTO',
'to':'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': '1515471851389',
'sign': 'e3c50e9bd1103e10992ee9f04b9b4c5f',
'doctype': 'json',
'version': 2.1,
'keyfrom': 'fanyi.web',
'action': 'FY_BY_CLICKBUTTION',
'typoResult': False
}
data = urllib.urlencode(form_data)
request = urllib2.Request(url, data=data, headers=headers)
request.add_header('User-agent', user_agent)
response = urllib2.urlopen(request)
print (response.read())
4.cookie操作
1.保存cookie数据到文件夹
import urllib2
import cookielib
#创建一个cookie对象
cookie = cookielib.MozillaCookieJar('baidu.txt')
#创建一个Handler操作对象
cookie_handler = urllib2.HTTPCookieProcessor(cookie)
#创建一个opener对象
cookie_opener = urllib2.build_opener(cookie_handler)
#访问目标url
response = cookie_opener.open('https://www.baidu.com')
#访问结束后,得到服务器响应的cookie数据已经存在,将数据保存
cookie.save()
————————————————————————————————————————————————————————————————————————————
2.使用保存的cookie数据
import urllib2
import cookielib
#创建一个cookie对象
cookie = cookielib.MozillaCookieJar()
#从文件中加载cookie数据
cookie.load('baidu.txt')
#创建一个Handler对象
cookie_Handler = urllib2.HTTPCookieProcessor(cookie)
#创建一个opener对象
cookie_opener = urllib2.build_opener(cookie_handler)
#访问目标url
response = cookie_opener.open('https://www.baidu.com')
print(response.read())
二:requests模块的使用
1.通过一个小demo来了解requests的基本使用吧
import requests
#发送请求
content = requests.get('https://www.taobao.com')
cont = content.text
#保存数据
with open('cont.html', 'w') as f:
f.write(cont.encode('utf-8))
2.post/get请求
get请求参数
import requests
#定义get参数,是一个字典数据
get_param = {'wd': '火车票'}
#get参数,通过params参数赋值,直接传递
response = requests.get('https://www.baidu.com', params=get_params)
#打印数据
print(response.text)
——————————————————————————————————————————————————————————————————————————————
post请求参数
import requests
#定义post参数
post_data = {
"i": "hello",# 要翻译的词语
"from": "AUTO", # 词语的翻译之前的语言
"to": "AUTO", # 词语翻译之后的语言
"smartresult": "dict", # 数据类型
"client": "fanyideskweb", # 客户端标识
"salt": 124141234234, # ~~~~可能是~~~时间
"sign": 'a87123912423423435',# ~~~~可能是~~~~md5
"doctype": "json", # 数据类型
"version": 2.1,# 版本号
"keyfrom": "fanyi.web",# 关键字
"action": "FY_BY_REALTIME",# 行为描述
"typoResult": False # 结果类型
}
#发送请求,得到相应的数据
response = requests.post('http://fanyi.youdao.com', data = post_data)
#打印获取到的数据
content = response.text
print(content)
- requests模块实际应用的很多,具体的requests操作请参考简书文章里的专门介绍
三:结构化数据处理
1.队列
队列:一种数据结构,是一种可以按照指定的规则进行数据排序,通过指定的操作手法进行数据的添加和提取的容器
队列的重点:常见的队列操作【LILO 队列】后进后出
队列的特点:线性安全的
常见队列:LILO队列,FIFO队列【先进先出】——话不对说,干货走起
import Queue
q1 = Queue.Queue()
#添加数据
q1.put('a')
q1.put('b')
q1.put('c')
q1.put('d')
q1.put('e')
#打印展示队列数据
print(q1.queue)
#从队列中获取数据【获取3条数据】
print(q1.get())
print(q1.get())
print(q1.get())
ps:数据的获取安装队列的数据先进先出,后进后出输出
2.栈队列【LIFO】先进后出
import Queue
q2 = Queue.Queue()
#添加数据
q2.put('1')
q2.put('2')
q2.put('3')
q2.put('4')
q2.put('5')
#展示栈队列数据,数据数量共几条【5】
print (q2.queue)
print(q2.qsize())
#取出数据3条
print (q2.get())
print (q2.get())
print (q2.get())
#展示剩余栈队列数据,和数量
print(q2.queue)
print(q2.qsize())#数量为2
3.优先队列:添加的数据在提取时符合一定的优先规则
q3 = Queue.PriorityQueue()
.......
4.两端队列
import Queue
q4 = Queue.deque()
#从队列的右端添加数据,常规操作
q4.append('a')
#从队列的左端添加数据
q4.appendleft('b')
#从队列的右端获取并移除数据
q4.pop()
#从左端获取并删除数据
q4.popleft()
5.多线程爬虫
- 多线程[多进程]:之前由一个线程/进程完成的程序执行任务,扩展成为多个线程/进程同时执行程序任务,提高处理性能的一种手段
- 多线程爬虫时要注意数据的隔离和共享——队列【queue】
import requests
import queue
import threading
#多线程访问共享数据 |Rlock()当前线程频繁访问自己的数据
lock = threading.Lock()
#1.模拟接到的数据,是从N个url地址中获取的
#创建一个保存url地址的LILO队列
url_queue = Queue.Queue()
#模拟添加所有需要爬取的地址
for page in range(0, 15)#爬取14个地址中的数据
url_queue.put('https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn=' + str(page*50))
#打印爬取的数据队列中的url
print(url_queue.queue)
#2.核心爬虫程序
def spider(urlqueue):
#开始爬取:当urlqueue队列中,还有未操作的url地址,爬虫不停止
while urlqueue.qsize() >0:
if lock.acquire():#给肯定出现数据访问冲突的代码加锁
url = urlqueue.get()
#开始爬取数据操作
print('剩余数据:%s--线程%s开始对%s进行爬取' % (urlqueue.qsize(), threading.currentThread().name, url))
headers = {
"Referer": url,
"User-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.7 Safari/537.36"
}
response = requests.get(url, headers=headers)
#文件名-截取url地址倒数后十位为文件名称
filename = url[-10:]+ '.html'
with open(filename, 'w') as f:
f.write(response.text.encode('utf-8'))
#爬取结束,当前执行完成,解锁
lock.release()
3.指定多线程
if __name__ == '__main__':
#声明一个变量保存多线程
threads = []
#声明一个变量控制启动的线程数量
threads_num = 3 #启动3个线程
#创建线程对象
for ct in range(0, threads_num):
current_thread = threading.Thread(target=spider, args=(url_queue,))
current_thread.start()
#将线程保存到列表
threads.append(current_thread)
#让所有的线程join,就是让主线程等待所有子线程结束在退出
for t in threads:
t.join()
print('程序执行结束......')
6.正则表达式
1.快捷的正则
import re
#定义正则表达式
regexp = r'\d+'
#定义目标字符串
intor = 'this is good boy and 18 years old'
#直接匹配得到结果
data = re.findall(regexp, intor)
print data
_____________________________________________________________________________________________
2.核心正则
import re
#定义一个正则表达式
regexp = r'\d+'
#编译得到的正则匹配对象
patt = re.compile(regexp)
#定义目标字符串
intor = 'this is good boy and 18 years old'
#匹配得到数据
data = patt.findall(intor)
print data
————————————————————————————————————————————————————————————————
3.正则常用函数
match():用于根据表达式进行字符串匹配的操作函数,只匹配一次【从指定的起始位置进行匹配】
search():用于根据表达式进行字符串匹配的操作函数,只匹配一次【从完整的目标字符串中进行检索匹配】
findall():用于根据表达式进行字符串匹配,匹配多次,返回匹配到的列表
finditer():用于根据表达式进行字符串匹配,匹配多次,返回匹配的迭代器
split():根据指定的表达式对目标字符串进行切割,返回切割后的列表
sub():字符串替换
#匹配对象的函数
match(string[, pos[, endpos]])
search(string[, pos[, endpos]])
findall(string[, pos[, endpos]])
finditer(string[, pos[, endpos]])
# re模块的函数
match(pattern, string, flags=0)
search(pattern, string, flags=0)
findall(pattern, string, flags=0)
finditer(pattern, string, flags=0)
#公共函数【匹配对象|re模块操作方式一样】
split():切割字符串
sub():替换字符串
import re
#定义目标字符串
intor = 'this is good boy and age is 18 years old'
#定义正则表达式
r1 = 'is'
r2 = '18'
#编译匹配对象
p1 = re.compile(r1)
p2 = re.compile(r2)
##match函数
print(p1.match(intor).group())
print(p2.match(intor))
print(p2.match(intor, 10).group())
##search函数
print(p1.search(intor).group())
print(p2.search(intor))
print(p2.search(intor, 10).group())
##findall函数
print(p1.findall(intor))
##finditer函数
print(p1.finditer(intor))
for p in p1.finditer(intor):
print(p, p.group, p.span(), p.start(), p.end())
##re.match():主要执行目标字符串是否以指定的表达式匹配的字符开头
r_match = re.match(r'this', intor)
print(r_match.group(), r_match.span())
r2_match = re.amtch(r'18', intor)
print(r2_match)
##re.search():全文匹配第一次出现的位置
r_search = re.search(r'is', intor)
print(r_search.group(), r_search.span()
##re,findall():全文匹配,不能指定位置
r_findall = re.findall(r'is', intor)
print(r_findall)
##re.finditer():全文匹配得到迭代器
r_finditer = re.finditer(r'is', intor)
for i in r_finditer:
print(i, i.group(), i.span())
##split():切片
s_list = re.split(r'\s', intor)
print(s_list)
m_list = re.split(r's', intor)
print(m_list)
#组合字符串
i ='s'.join(m_list)
print(i)
##replace():替换
intor_new = intor.resplace('s', 'm')#m替代s
print(intor_new)
intor_new2 = intor.replace('s', 'mm', 2)#mm替换前两个s
print(intor_new2)
##sub():正则表达式中的替换
intor_new3 = re.sub(r'\d+','mm', intor)#mm替换文中数字
print(intor_new3)
intro = 'hello python are you ok?'
regext = r'(py(th)on)'
value = re.search(regext,intro)
print(value.group(), value.group(0),value.group(1),value.group(2))#('python', 'python', 'python', 'th')
——————————————————————————————————————————————————————————————————————————————————
html = '<div> i am div </div><p>ooooo</p><div> i am coming </div>'
regext2 = r'<div>.*</div>'#贪婪模式
regext3 = r'<div>.*?</div>'#非贪婪模式
regext4 = r'<div>(.*?)</div>'#非贪婪模式
value2 = re.findall(regext2,html)
value3 = re.findall(regext3,html)
value4 = re.findall(regext4,html)
print value2
print value3
print value4
#输出如下
'''
['<div> i am div </div><p>ooooo</p><div> i am coming </div>']
['<div> i am div </div>', '<div> i am coming </div>']
[' i am div ', ' i am coming ']
'''
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
##正则爬虫运用
import requests
import re
#抓取数据的路径
url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E7%BE%8E%E5%A5%B3&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word=%E7%BE%8E%E5%A5%B3&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn=60&rn=30&gsm=3c&1515661160078='
#请求头
headers = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, br',
'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8',
'Cache-Control':'max-age=0','Connection':'keep-alive',
'Host':'image.baidu.com',
'Referer':'https://image.baidu.com/search/index?ct=201326592&cl=2&st=-1&lm=-1&nc=1&ie=utf-8&tn=baiduimage&ipn=r&rps=1&pv=&fm=rs1&word=%E7%BE%8E%E5%A5%B3%E5%9B%BE%E7%89%87&oriquery=%E5%9B%BE%E7%89%87&ofr=%E5%9B%BE%E7%89%87&sensitive=0',
'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36'
}
#第一次爬取,得到图片展示数据
response1 = requests.get(url, headers=headers)
response1.encoding('utf-8')
content = response1.text
#正则匹配得到照片路径,根据路径爬取照片
img_list = re.findall(r'"thumbURL":"(.*?)"', content)
#循环爬取图片,保存到本地
for img_url in img_list:
response2 = requests.get(img_url)
#开始保存
filename = img_url[-20:]/replace('/', '_')
with open(filename, 'wb') as f:
f.write(response2.content)
7.Xpath
- xpath:python通过xml模块进行操作
from lxml import etree
import requests
response = requests.get('http://www.baidu.com')
content = response.text.encode('utf-8')
#从文件中加载html文档数据
#html = etree.parse(filename)
#爬虫直接获取数据
html = etree.HTML(content)
#获取数据,直接操作标签
data_h1 = html.xpath('//div')
print(data_h1[0].text)
print(data_h1[0].xpath('string(.)'))
#2.获取数据-操作标签的属性
data_h2 = html.xpath('//div[@id=title1]')
print(data_h2)
print(data_h2[0].text)
data_h3 = html.xpath('//div[@id=title2]')
print(data_h3)
print(data_h3[0].text)
print(data_h3[0].xpath('string(.)'))
#3.通过属性执行获取标签对象
data_h4 = html.xpath('//body/p[@class = "content"]')#获取body下的所有p标签
print(data_h4)
for i in data_h4:
print (i.text)
data_h5 = html.xpath('//body/p[@class = "content"][1]')#获取body下的所有p 标签
print(data_h5[0].text)
8.bs4————DOM操作/CSS操作
- 安装bs4:
1.pip install beautifulsoup4
2.easy_install beautifulsoup4
3.下载tar.gz包。pip setup.py install
from bs4 import BeautifulSoup
#加载网页数据
#1.从爬虫爬取到网页数据加载
#soup = BeautifulSoup(response.text.encode('utf-8')
#2.从网页文件直接加载数据
soup = BeautifulSoup(open('index.html'), lxml)
print(soup)#soup对象,包含整个DOM模型树
————————————————————————————————————————————————————————————————————————————————————————————
————标签操作————
#bs4通过soup对象直接操作标签,检索文档中是否包含这个标签
#获取标签对象title标签
print(soup.title)#得到<title>bs4</title>
#操作标签的属性
print(soup.h1)#操作h1标签得到<h1 class="intor">mmmmmmmmmmm</h1>
print(soup.h1.attrs)#操作得到h1标签的属性得到{'class': ['intor']}
print(soup.h1.attrs.get('class'))#['intor']
print(soup.h1.attrs['class'])#['intor']
print(soup.h1.string)#获取标签内容
——————————————————————————————————————————————————————————————————————————————————————
————DOM操作————
#DOM属性
#查询body中的所有子标签
print(soup.body)#获取到子标签列表
'''
输出
<body>
<h1 class="intor">mmmmmmmmmmm</h1>
</body>
'''
print(soup.body.children)#获取得到子标签列表迭代器
# <listiterator object at 0x0000000003986780>
for child in soup.body.children:
print(child.string)#输出mmmmmmmmmmm
# print(dir(soup))
#################################DOM操作根据标签名称查询
h = soup.find_all('h1')#根据标签查询标签及内容
print(h)#[<h1 class="intor">mmmmmmmmmmm</h1>]
#根据名称的正则表达式进行查询
import re
h_r = soup.find_all(re.compile('m'))
print(h_r)
#一次查询多个标签
h_r2 = soup.find_all(['div', 'h1', 'h2'])
print(h_r2)#[<h1 class="intor">mmmmmmmmmmm</h1>, <h2>mmmmmmmmmmm</h2>, <div>mmmmmmmmmmm</div>]
#关键字参数:通过attrs将标签的属性和属性值作为字典数据进行数据查询操作
h_r3 = soup.find_all(attrs={'class':'intor'})
print(h_r3)#[<h1 class="intor">mmmmmmmmmmm</h1>]
#内容查询
h_r4 = soup.find_all(text='mmmmmmmmmmm')#内容必须完整
print(h_r4)#[u'mmmmmmmmmmm', u'mmmmmmmmmmm', u'mmmmmmmmmmm']
——————————————————————————————————————————————————————————————————————————————————————————————————————————
————CSS操作————
#css操作,核心操作函数:select()
#1.标签选择器
s1 = soup.select('div')
print(s1)#[<div>mmmmmmmmmmm</div>]
#2.id选择器
s2 = soup.select('#titl')
print(s2)#[<h2 id="titl">mmmmmmmmmmm</h2>]
#3.class选择器
s3 =soup.select('.intor')
print(s3)#[<h1 class="intor">mmmmmmmmmmm</h1>]
#4.包含选择器
# s4 = soup.select('#contenter p')#匹配属性contenter下的p标签
# print(s4)
# #5.子类选择器
# s5 = soup.select('#contenter > p')#匹配属性contenter下的p标签
# print(s5)
#6.属性选择
s6 = soup.select('h1[class]')
print(s6)#[<h1 class="intor">mmmmmmmmmmm</h1>]
s7 = soup.select('h2[id="titl"]')
print(s7)#[<h2 id="titl">mmmmmmmmmmm</h2>]
未完待续..........
(欢迎加入Python交流群:930353061。人生苦短,我用python!!!)