3、Python 定向爬虫入门
1、基本的正则表达式
1-2正则表达式符号与方法
常用符号
. 匹配任意字符,换行符\n除外 (占位符,几个点就是几个占位符)
* 匹配前一个字符0次或无限次
? 匹配前一个字符0次或1次
.* 贪心算法
.*?非贪心算法
() 括号内的数据作为结果返回
常用方法
findall匹配所有符合规律的内容,返回包含结果的列表
search 匹配并提取第一个符合规律的内容,返回一个正则表达式对象(object)
sub替换符合规律的内容,返回替换后的值
常用技巧
import re (推荐)
from re import * (不推荐)
from re import findall,search,sub,S (不推荐)
不需要compile
使用\d+匹配纯数字
re.S – 让点的范围匹配任何字符(包括\n),任何一行
1-3正则表达式的应用举例
import re
匹配多段内容
灵活使用findall与search
先抓大再抓小
实现翻页
#-*-coding:utf8-*-
#导入re库文件
import re
old_url = 'http://www.jikexueyuan.com/course/android/?pageNum=2'
total_page = 20
f = open('text.txt','r')
html = f.read()
f.close()
#爬取标题
# title = re.search('<title>(.*?)</title>',html,re.S).group(1)
# print title
#爬取链接
# links = re.findall('href="(.*?)"',html,re.S)
# for each in links:
# print each
#抓取部分文字,先大再小
# text_fied = re.findall('<ul>(.*?)</ul>',html,re.S)[0]
# print text_fied
# the_text = re.findall('">(.*?)</a>',text_fied,re.S)
# for every_text in the_text:
# print every_text
#sub实现翻页
for i in range(2,total_page+1):
new_link = re.sub('pageNum=\d+','pageNum=%d'%i,old_url,re.S)
print new_link
1-4实战——制作文本爬虫
目标网站:http://www.jikexueyuan.com/
目标内容:课程图片
实现原理:
1.保存网页源代码
2.Python读文件加载源代码
3.正则表达式提取图片网址
4.下载图片
#-*-coding:utf8-*-
import re
import requests
#读取源代码文件
f = open('source.txt','r')
html = f.read()
f.close()
#匹配图片网址
pic_url = re.findall('img src="(.*?)" class="op-img-others c-img c-img6"',html,re.S)
i = 0
for each in pic_url:
print 'now downloading:' + each
pic = requests.get(each)
fp = open('pic\\' + str(i) + '.jpg','wb')
fp.write(pic.content)
fp.close()
i += 1
2、Python 单线程爬虫
2-1 Requests介绍和安装
Requests安装
Windows: pip install requests (在目录C:\Python27\Scripts)
Linux: sudo pip install requests
第三方库安装技巧
少用easy_install因为只能安装不能卸载
多用pip方式安装
撞墙了怎么办?请戳->http://www.lfd.uci.edu/~gohlke/pythonlibs/
下载后将.whl重命名为.zip
2-2 第一个网页爬虫
直接获取源代码
import requests
html = requests.get('http://tieba.baidu.com/')
print html.text
修改http头获取源代码
#hd是我们自己构造的一个字典,里面保存了user-agent
hd = {'User-Agent':'Mozilla/5.0(Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/41.0.2272.118 Safari/537.36'}
html = requests.get('http://jp.tingroom.com/yuedu/yd300p/',headers= hd)
Requests与正则表达式
单线程简单爬虫原理 – 使用requests获取网页源代码,再使用正则表达式匹配出感兴趣的内容
#-*—coding:utf8-*-
import requests
import re
#下面三行是编码转换的功能,大家现在不用关心。
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
#hd是我们自己构造的一个字典,里面保存了user-agent
hd = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'}
# html = requests.get('http://jp.tingroom.com/yuedu/yd300p/')
html = requests.get('http://jp.tingroom.com/yuedu/yd300p/',headers = hd)
html.encoding = 'utf-8' #这一行是将编码转为utf-8否则中文会显示乱码。
print html.text
title = re.findall('color:#666666;">(.*?)</span>',html.text,re.S)
for each in title:
print each
chinese = re.findall('color: #039;">(.*?)</a>',html.text,re.S)
for each in chinese:
print each
2-3 向网页提交数据
Get与post介绍
Get是从服务器上获取数据
Post是向服务器传送数据
Get通过构造url中的参数来实现功能
Post将数据放在header提交数据
分析目标网站
网站地址:https://www.crowdfunder.com/browse/deals
分析工具:Chrome-审核元素-Network
Request 表单提交
核心方法:request.post
核心步骤:构造表单-提交表单-获取返回信息
异步加载
#-*-coding:utf8-*-
import requests
import re
# url = 'https://www.crowdfunder.com/browse/deals'
url = 'https://www.crowdfunder.com/browse/deals&template=false'
# html = requests.get(url).text
# print html
#注意这里的page后面跟的数字需要放到引号里面。
data = {
'entities_only':'true',
'page':'2'
}
html_post = requests.post(url,data=data)
title = re.findall('"card-title">(.*?)</div>',html_post.text,re.S)
for each in title:
print each
2-4 实战-极客学院课程爬虫
目标网站:http://www.jikexueyuan.com/course/
目标内容:课程名称,课程介绍,课程时间,课程等级,学习人数
涉及知识:
Requests获取网页
re.sub换页
正则表达式匹配内容
#-*_coding:utf8-*-
import requests
import re
import sys
reload(sys)
sys.setdefaultencoding("utf-8")#在windows下命令提示符默认的编码是GBK, 而网页是utf-8,将windows下命令提示符的编码方式强制转化为utf-8
class spider(object):
def __init__(self):
print u'开始爬取内容。。。'
#getsource用来获取网页源代码
def getsource(self,url):
html = requests.get(url)
return html.text
#changepage用来生产不同页数的链接
def changepage(self,url,total_page):
now_page = int(re.search('pageNum=(\d+)',url,re.S).group(1))
page_group = []
for i inrange(now_page,total_page+1):
link = re.sub('pageNum=\d+','pageNum=%s'%i,url,re.S)
page_group.append(link)
return page_group
#geteveryclass用来抓取每个课程块的信息
def geteveryclass(self,source):
everyclass = re.findall('(<li deg="".*?</li>)',source,re.S)
return everyclass
#getinfo用来从每个课程块中提取出我们需要的信息
def getinfo(self,eachclass):
info = {}
info['title'] =re.search('target="_blank">(.*?)</a>',eachclass,re.S).group(1)
info['content'] = re.search('</h2><p>(.*?)</p>',eachclass,re.S).group(1)
timeandlevel = re.findall('<em>(.*?)</em>',eachclass,re.S)
info['classtime'] = timeandlevel[0]
info['classlevel'] = timeandlevel[1]
info['learnnum'] = re.search('"learn-number">(.*?)</em>',eachclass,re.S).group(1)
return info
#saveinfo用来保存结果到info.txt文件中
def saveinfo(self,classinfo):
f = open('info.txt','a')
for each inclassinfo:
f.writelines('title:' + each['title'] +'\n')
f.writelines('content:' + each['content'] +'\n')
f.writelines('classtime:' + each['classtime'] +'\n')
f.writelines('classlevel:' + each['classlevel'] +'\n')
f.writelines('learnnum:' + each['learnnum'] +'\n\n')
f.close()
if __name__ == '__main__':
classinfo = []
url = 'http://www.jikexueyuan.com/course/?pageNum=1'
jikespider = spider()
all_links = jikespider.changepage(url,20)
for link inall_links:
print u'正在处理页面:'+ link
html = jikespider.getsource(link)
everyclass = jikespider.geteveryclass(html)
for each ineveryclass:
info = jikespider.getinfo(each)
classinfo.append(info)
jikespider.saveinfo(classinfo)
课程总结
1) requests获取网页源代码
2) 修改Http头绕过简单的反爬虫机制
3) 向网页提交内容
3、XPath 与多线程爬虫
3-1 XPath的介绍与配置
XPath – XML Path language
XPath 是一门语言
XPath可以在XML文档中查找信息
XPath支持HTML
XPath通过元素和属性进行导航
XPath可以用来提取信息
XPath比正则表达式厉害
XPath比正则表达式简单
安装使用XPath
安装lxml库
from lxmlimport etree
Selector =etree.HTML(网页源代码)
Selector.xpath(一段神奇的符号)
3-2 神器XPath的使用
XPath与HTML结构
获取网页元素的XPath
1) 手动分析法
2) Chrome生成法 (右键对象 -> copyXPath)
XPath提取内容
//定位根节点
/往下层寻找
提取文本内容:/text()
提取属性内容: /@xxxx
3-3 XPath的特殊用法
以相同的字符开头
1)starts-with(@属性名称,属性字符相同部分)
<div id="test-1">需要的内容1</div>
<div id="test-2">需要的内容2</div>
<divid="testfault">需要的内容3</div>
标签套标签
2) string(.)
<div id=“class3”>美女,
<font color=red>你的微信是多少?</font>
</div>
3-4 python并行化介绍与演示
Python并行化介绍
多个线程同时处理任务
高效
快速
map的使用
map 函数一手包办了序列操作、参数传递和结果保存等一系列的操作。
frommultiprocessing.dummy import Pool
pool = Pool(4) # 计算机有4个核
results =pool.map(爬取函数,网址列表)
3-5 实战 – 百度贴吧爬虫
目标网站:http://tieba.baidu.com/p/3522395718
目标内容:跟帖用户名,跟帖内容,跟帖时间
涉及知识:
Requests获取网页
XPath提取内容
map实现多线程爬虫
课程总结
使用Xpath提取网页内容
使用map实现多线程爬虫