1.正则表达式解析(百度贴吧)
利用正则表达式进行匹配
# -*- coding:utf-8 -*-
import urllib
import urllib2
import re
class Spider:
def __init__(self, kw):
self.page = 1
self.kw = kw
self.switch = True
def writePage(self, content):
'''
写入每页的数据
'''
with open('log.txt', 'a') as f:
f.write(content)
def loadPage(self):
'''
下载界面
'''
# 组合url
url = 'http://tieba.baidu.com/f?'
# 编码
key = urllib.urlencode({'kw':self.kw})
pn = (self.page-1) * 50
print(pn)
fullurl = url + key + '&pn=' + str(pn)
headers = {'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.3'}
request = urllib2.Request(fullurl, headers=headers)
response = urllib2.urlopen(request)
# 获取每页的html源码
html = response.read()
# 创建正则表达式规则对象,匹配每页里的内容
# pattern = re.compile("<div\sclass='threadlist_title.pull_left.j_th_tit'><a\s(.*?)>(.*?)</a></div>", re.S)
# pattern = re.compile('<div\sclass="threadlist_title pull_left j_th_tit ">(.*?)</div>', re.S)
pattern = re.compile('<a\srel="noreferrer".*?\sclass="j_th_tit ">(.*?)</a>', re.S)
# 将正则匹配对象应用到html源码中,返回所有帖子的列表
content_list = pattern.findall(html)
for content in content_list:
msg = content + '\n'
self.writePage(msg)
def startWork(self):
'''
控制爬虫运行
'''
while self.switch:
msg = '这是第'+ str(self.page) +'页'+ '\n'
self.writePage(msg)
self.loadPage()
print('这是第%s页' %self.page)
c = raw_input('是否继续?(返回请输入q)')
if c == 'q':
self.switch = False
self.page += 1
print('谢谢使用!')
if __name__=='__main__':
kw = raw_input('请输入想要爬取的贴吧名:')
s = Spider(kw)
s.startWork()
2.xpath解析(百度贴吧)
利用lxml库进行匹配
# -*- coding:utf-8 -*-
import urllib
import urllib2
from lxml import etree
def loadPage(url):
'''
作用:根据url发送请求,获取服务器响应文件
url:爬取的url地址
'''
headers = {
'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
}
request = urllib2.Request(url, headers=headers)
html = urllib2.urlopen(request).read()
# 解析html文档为html DOM模型
# 返回所有成功匹配的集合
link_list = etree.HTML(html).xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href')
for link in link_list:
# 组合为每个帖子的链接
fulllink = "http://tieba.baidu.com" + link
loadImage(fulllink)
def loadImage(link):
'''
取出每个帖子里的每个图片的链接
link:每个帖子的链接
'''
headers = {
'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
}
request = urllib2.Request(link, headers=headers)
html = urllib2.urlopen(request).read()
# 解析,返回匹配成功的集合
link_list = etree.HTML(html).xpath('//img[@class="BDE_Image"]/@src')
print(link_list)
for link in link_list:
# 组合为每个图片的链接
writePage(link)
def writePage(link):
'''
作用:下载图片到本地
link:图片的链接
'''
headers = {
'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
}
request = urllib2.Request(link, headers=headers)
image = urllib2.urlopen(request).read()
# 取出链接后10位作为文件名
filename = link[-10:]
with open(filename, 'wb') as f:
f.write(image)
print('已经成功下载' + filename)
def tiebaSpider(url, beginPage, endPage):
'''
作用:贴吧爬虫调度器,处理组合处理每个界面的url
url:贴吧url的前部分
beginPage:起始页
endPage:结束页
'''
for page in range(beginPage, endPage + 1):
pn = (page-1) * 50
fullurl = url + '&pn=' + str(pn)
filename = '第' + str(page) + '页.html'
print(filename)
loadPage(fullurl)
# writePage(html, filename)
print('谢谢使用')
if __name__=='__main__':
kw = raw_input('请输入爬取的贴吧名:')
beginPage = int(raw_input('请输入起始页:'))
endPage = int(raw_input('请输入结束页:'))
# 组合url
url = 'http://tieba.baidu.com/f?'
# 编码
key = urllib.urlencode({'kw':kw})
fullurl = url + key
3.bs4解析
利用bs4库中的BeautifulSop进行匹配
# -*- coding:utf-8 -*-
from bs4 import BeautifulSop
import request
def login():
# 构建一个session对象,可以保存cookie
sess = request.Session
headers = {
'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
}
# 首先获取登录界面,找到需要的post数据,同时会记录当前网页的cookie值
html = sess("https://www.zhihu.com/signin", headers=headers).text
bs = BeautifulSoup(html)
# 获取之前get页面的_xsrf值
_xsrf = bs.find('input', attrs={"name":"_xsrf"}).get('value')
print(_xsrf)
if __name__=='__main__':
login()
4.json解析(豆瓣电影)
利用json库解析json数据
(1)json.load()
把json格式字符串解码成Python对象
json | python |
---|---|
object | dict |
array | list |
string | unicoe |
number(int) | int,long |
number(real) | float |
true | True |
false | False |
null | None |
(2)json.dump(s)
把Python对象编码转换成json字符串
json | python |
---|---|
object | dict |
array | list |
string | unicoe |
number | int,long,float |
true | True |
false | False |
null | None |
(3)json与xpath的区别
json结构清晰,可读性高,复杂度低,非常容易匹配
xpath | json | 描述 |
---|---|---|
/ | $ | 根节点 |
. | @ | 现行节点 |
/ | . or [ ] | 取子节点 |
.. | n/a | 取父节点,jsonpath未支持 |
// | .. | 就是不管位置,选择所有符合条件的条件 |
* | * | 匹配所有原始节点 |
@ | n\a | 根据属性访问,json不支持,因为json是个key-value递归结构 |
[ ] | [ ] | 迭代器标示(可以在里面做简单的迭代操作) |
| | [ ,] | 支持迭代器做多选 |
[ ] | ?() | 支持过滤操作 |
n/a | () | 支持表达式运算,xpath不支持 |
() | n/a | 分组,json不支持 |
# -*- coding:utf-8 -*-
import urllib2
# json解析库,对应到lxml
import json
# json解析语法,对应到xpath
import jsonpath
url = 'https://movie.douban.com/j/new_search_subjects?'
headers = {'User-Agent':'Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)'}
request = urllib2.Request(url, headers=headers)
response = urllib2.urlopen(request)
# 取出json文件里的字符串内容
html = response.read()
# 把json形式的字符串转换程Python形式的Unicode字符串
unicodestr = json.loads(html)
city_list = jsonpath.jsonpath(unicodestr, '$..title')
for item in city_list:
print(item)
# dumps()默认中文为ascii编码格式,ensure_ascii默认为True
# 禁用ascii编码格式,返回的是unicode字符串,方便使用
# dumps()和dump()的区别:dumps()转换的在线列集合,dump()转换的是文档中的集合
array = json.dumps(city_list, ensure_ascii=False)
# 写入文件
with open('title.json','w') as f:
f.write(array.encode('utf-8'))