python运行时,出现以下情形:该文件没有关联的应用来执行该操作。请安装应用....... 请问excel怎么给文件加密解决?

python 爬虫教程
python 爬虫教程
From:如何入门 python 爬虫:Python爬虫入门教程:Python爬虫之Selenium+Phantomjs+CasperJS:静觅 崔庆才的个人博客 python 爬虫系列:python爬虫从入门到放弃系列博客:爬虫入门初级篇IDE 选择: PyCharm(推荐)、SublimeText3、VS2015、wingIDE装python2还是python3 ?python社区需要很多年才能将现有的模块移植到支持python3. django web.py flask等还不支持python3。所以推荐安装python2 最新版。Windows 平台从 http://python.org/download/ 上安装Python 2.7。您需要修改 PATH 环境变量,将Python的可执行程序及额外的脚本添加到系统路径中。将以下路径添加到 PATH 中:C:\Python2.7\;C:\Python2.7\Scripts\; 。从 http://sourceforge.net/projects/pywin32/ 安装 pywin32。 请确认下载符合您系统的版本(win32或者amd64)Linux Ubuntu 平台安装Python : sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev学习需求:抓取的某个网站或者某个应用的内容,提取有用的价值实现手段:模拟用户在浏览器或者应用(app)上的操作,实现自动化的程序爬虫应用场景(利用爬虫能做什么?)大家最熟悉的应用场景:抢票神器(360抢票器)、投票神器(微信朋友圈投票)企业应用场景爬虫是什么?专业术语: 网络爬虫(又被称为网页蜘蛛,网络机器人)网络爬虫,是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。爬虫起源(产生背景)随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战;搜索引擎有Yahoo,Google,百度等,作为一个辅助人们检索信息的工具成为用户访问万维网的入口和指南。网络爬虫是搜索引擎系统中十分重要的组成部分,它负责从互联网中搜集网页,采集信息,这些网页信息用于建立索引从而为搜索 引擎提供支持,它决定着整个引擎系统的内容是否丰富,信息是否即时,因此其性能的优劣直接影响着搜索引擎的效果。网络爬虫程序的优劣,很大程度上反映了一个搜索引擎的好差。不信,你可以随便拿一个网站去查询一下各家搜索对它的网页收录情况,爬虫强大程度跟搜索引擎好坏基本成正比。搜索引擎工作原理第一步:抓取网页(爬虫)搜索引擎是通过一种特定规律的软件跟踪网页的链接,从一个链接爬到另外一个链接,像蜘蛛在蜘蛛网上爬行一样,所以被称为“蜘蛛”也被称为“机器人”。搜索引擎蜘蛛的爬行是被输入了一定的规则的,它需要遵从一些命令或文件的内容。
Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取https://www.taobao.com/robots.txthttp://www.qq.com/robots.txthttps://www.taobao.com/robots.txt示例 CSDN robot.txt ( https://blog.csdn.net/robots.txt )文件中 Sitemap:# -*- coding: UTF-8 -*-
import requests
def download(url, user_agent=r'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0. Safari/537.36', num_retries=3):
print 'Downloading : ', url
headers = {'user-agent':user_agent}
#r = requests.get(url, head=headers) #get中参数head错误,可以看到引发异常
r = requests.get(url, headers=headers)
html = None
if r.status_code == 200:
print 'status_code : {0}'.format(r.status_code)
html = r.content
print 'status_code : {0}'.format(r.status_code)
except BaseException as ex:
print 'Download error : ', ex
html = None
if num_retries & 0:
print 'Download fail and retry...'
return download(url, user_agent, num_retries-1)
return html
if __name__ == "__main__":
url = r'https://blog.csdn.net/s/sitemap/pcsitemapindex.xml'
sitemap = download(url)
links = re.findall(r'&loc&(.*?)&/loc&', sitemap)
for link in links:
print link
pass第二步:数据存储搜索引擎是通过蜘蛛跟踪链接爬行到网页,并将爬行的数据存入原始页面数据库。其中的页面数据与用户浏览器得到的HTML是完全一样的。搜索引擎蜘蛛在抓取页面时,也做一定的重复内容检测,一旦遇到权重很低的网站上有大量抄袭、采集或者复制的内容,很可能就不再爬行。第三步:预处理搜索引擎将蜘蛛抓取回来的页面,进行各种步骤的预处理。⒈提取文字 ⒉中文分词 ⒊去停止词 ⒋消除噪音(搜索引擎需要识别并消除这些噪声,比如版权声明文字、导航条、广告等……) 5.正向索引 6.倒排索引 7.链接关系计算 8.特殊文件处理。 除了HTML文件外,搜索引擎通常还能抓取和索引以文字为基础的多种文件类型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。我们在搜索结果中也经常会看到这些文件类型。但搜索引擎还不能处理图片、视频、Flash 这类非文字内容,也不能执行脚本和程序。第四步:排名,提供检索服务但是,这些通用性搜索引擎也存在着一定的局限性,如:(1)不同领域、不同背景的用户往往具有不同的检索目的和需求,通用搜索引擎所返回的结果包含大量用户不关心的网页。(2)通用搜索引擎的目标是尽可能大的网络覆盖率,有限的搜索引擎服务器资源与无限的网络数据资源之间的矛盾将进一步加深。(3)万维网数据形式的丰富和网络技术的不断发展,图片、数据库、音频、视频多媒体等不同数据大量出现,通用搜索引擎往往对这些信息含量密集且具有一定结构的数据无能为力,不能很好地发现和获取。(4)通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询。为了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。 聚焦爬虫是一个自动下载网页的程序,它根据既定的抓取目标,有选择的访问万维网上的网页与相关的链接,获取所需要的信息。与通用爬虫(general purpose web crawler)不同,聚焦爬虫并不追求大的覆盖,而将目标定为抓取与某一特定主题内容相关的网页,为面向主题的用户查询准备数据资源。聚焦爬虫工作原理以及关键技术概述网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。相对于通用网络爬虫,聚焦爬虫还需要解决三个主要问题:(1) 对抓取目标的描述或定义;(2) 对网页或数据的分析与过滤;(3) 对URL的搜索策略。抓取目标的描述和定义是决定网页分析算法与URL搜索策略如何制订的基础。而网页分析算法和候选URL排序算法是决定搜索引擎所提供的服务形式和爬虫网页抓取行为的关键所在。这两个部分的算法又是紧密相关的。网络爬虫的发展趋势随着AJAX/Web2.0的流行,如何抓取AJAX等动态页面成了搜索引擎急需解决的问题,如果搜索引擎依旧采用“爬”的机制,是无法抓取到AJAX页面的有效数据的。 对于AJAX这样的技术,所需要的爬虫引擎必须是基于驱动的。而如果想要实现事件驱动,首先需要解决以下问题:第一:JavaScript的交互分析和解释;第二:DOM事件的处理和解释分发;第三:动态DOM内容语义的抽取。爬虫发展的几个阶段(博士论文copy)第一个阶段可以说是早期爬虫,斯坦福的几位同学完成的抓取,当时的互联网基本都是完全开放的,人类流量是主流;第二个阶段是分布式爬虫,但是爬虫面对新的问题是数据量越来越大,传统爬虫已经解决不了把数据都抓全的问题,需要更多的爬虫,于是调度问题就出现了;第三阶段是暗网爬虫。此时面对新的问题是数据之间的link越来越少,比如淘宝,点评这类数据,彼此link很少,那么抓全这些数据就很难;还有一些数据是需要提交查询词才能获取,比如机票查询,那么需要寻找一些手段“发现”更多,更完整的不是明面上的数据。第四阶段智能爬虫,这主要是爬虫又开始面对新的问题:社交网络数据的抓取。社交网络对爬虫带来的新的挑战包括有一条账号护城河我们通常称UGC(User Generated Content)指用户原创内容。为web2.0,即数据从单向传达,到双向互动,人民群众可以与网站产生交互,因此产生了账号,每个人都通过账号来标识身份,提交数据,这样一来社交网络就可以通过封账号来提高数据抓取的难度,通过账号来发现非人类流量。之前没有账号只能通过cookie和ip。cookie又是易变,易挥发的,很难长期标识一个用户。网络走向封闭新浪微博在2012年以前都是基本不封的,随便写一个程序怎么抓都不封,但是很快,越来越多的站点都开始防止竞争对手,防止爬虫来抓取,数据逐渐走向封闭,越来越多的人难以获得数据。甚至都出现了专业的爬虫公司,这在2010年以前是不可想象的。。反爬手段,封杀手法千差万别写一个通用的框架抓取成百上千万的网站已经成为历史,或者说已经是一个技术相对成熟的工作,也就是已经有相对成熟的框架来”盗“成百上千的墓,但是极个别的墓则需要特殊手段了,目前市场上比较难以抓取的数据包括,微信公共账号,微博,facebook,ins,淘宝等等。具体原因各异,但基本无法用一个统一框架来完成,太特殊了。如果有一个通用的框架能解决我说的这几个网站的抓取,这一定是一个非常震撼的产品,如果有,一定要告诉我,那我公开出来,然后就改行了。当面对以上三个挑战的时候,就需要智能爬虫。智能爬虫是让爬虫的行为尽可能模仿人类行为,让反爬策略失效,只有”混在老百姓队伍里面,才是安全的“,因此这就需要琢磨浏览器了,很多人把爬虫写在了浏览器插件里面,把爬虫写在了手机里面,写在了路由器里面(春节抢票王)。再有一个传统的爬虫都是只有读操作的,没有写操作,这个很容易被判是爬虫,智能的爬虫需要有一些自动化交互的行为,这都是一些抵御反爬策略的方法。+从商业价值上,是一个能够抽象千百万网站抓取框架的爬虫工程师值钱,还是一个能抓特定难抓网站的爬虫工程师值钱?能花钱来买,被市场认可的数据,都是那些特别难抓的,抓取成本异常高的数据。目前市场上主流的爬虫工程师,都是能够抓成百上千网站的数据,但如果想有价值,还是得有能力抓特别难抓的数据,才能估上好价钱。爬虫基本原理爬虫是 模拟用户在浏览器或者某个应用上的操作,把操作的过程、实现自动化的程序当我们在浏览器中输入一个url后回车,后台会发生什么?比如说你输入http://www.sina.com.cn/简单来说这段过程发生了以下四个步骤:1.查找域名对应的IP地址。2.向IP对应的服务器发送请求。3.服务器响应请求,发回网页内容。4.浏览器解析网页内容。网络爬虫本质:本质就是浏览器http请求。浏览器和网络爬虫是两种不同的网络客户端,都以相同的方式来获取网页:网络爬虫要做的,简单来说,就是实现浏览器的功能。通过指定url,直接返回给用户所需要的数据, 而不需要一步步人工去操纵浏览器获取。浏览器是如何发送和接收这个数据呢? HTTP简介。HTTP协议(HyperText Transfer Protocol,超文本传输协议)目的是为了提供一种发布和接收HTML(HyperText Markup Language)页面的方法。HTTP协议所在的协议层(了解)HTTP是基于TCP协议之上的。在TCP/IP协议参考模型的各层对应的协议如下图,其中HTTP是应用层的协议。 默认HTTP的端口号为80,HTTPS的端口号为443。HTTP工作过程一次HTTP操作称为一个事务,其工作整个过程如下:1 ) 、地址解析,如用客户端浏览器请求这个页面:http://localhost.com:8080/index.htm从中分解出协议名、主机名、端口、对象路径等部分,对于我们的这个地址,解析得到的结果如下: 协议名:http 主机名:localhost.com 端口:8080 对象路径:/index.htm在这一步,需要域名系统DNS解析域名localhost.com,得主机的IP地址。2)、封装HTTP请求数据包把以上部分结合本机自己的信息,封装成一个HTTP请求数据包3)封装成TCP包,建立TCP连接(TCP的三次握手)在HTTP工作开始之前,客户机(Web浏览器)首先要通过网络与服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。这里是8080端口4)客户机发送请求命令建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容。5)服务器响应服务器接到请求后给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。实体消息是服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据6)服务器关闭TCP连接一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码Connection:keep-aliveTCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。HTTP协议栈数据流HTTPSHTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL。其所用的端口号是443。SSL:安全套接层,是netscape公司设计的主要用于web的安全传输协议。这种协议在WEB上获得了广泛的应用。通过证书认证来确保客户端和网站服务器之间的通信数据是加密安全的。有两种基本的加解密算法类型:1)对称加密(symmetrcic encryption):密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES,RC5,3DES等;对称加密主要问题是共享秘钥,除你的计算机(客户端)知道另外一台计算机(服务器)的私钥秘钥,否则无法对通信流进行加密解密。解决这个问题的方案非对称秘钥。2)非对称加密:使用两个秘钥:公共秘钥和私有秘钥。私有秘钥由一方密码保存(一般是服务器保存),另一方任何人都可以获得公共秘钥。这种密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。https通信的优点:客户端产生的密钥只有客户端和服务器端能得到;加密的数据只有客户端和服务器端才能得到明文;+客户端到服务端的通信是安全的。爬虫工作流程网络爬虫是捜索引擎(Baidu、Google、Yahoo)抓取系统的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。网络爬虫的基本工作流程如下:1.首先选取一部分精心挑选的种子URL;2.将这些URL放入待抓取URL队列;3.从待抓取URL队列中取出待抓取在URL,解析DNS,并且得到主机的ip,将URL对应的网页下载下来并存储到已下载网页库中。此外,将这些URL放进已抓取URL队列。4.分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环。import requests
#用来爬取网页
from bs4 import BeautifulSoup
#用来解析网页
#我们的种子
seds = ["http://www.lagou.com/"]
#我们设定终止条件为:爬取到10000个页面时,就不玩了
while sum & 10000 :
if sum & len(seds):
r = requests.get(seds[sum])
sum = sum + 1
#提取结构化数据;做存储操作
do_save_action(r)
soup = BeautifulSoup(r.content)
urls = soup.find_all("href",.....)
//解析网页所有的链接
for url in urls:
seds.append(url)
break# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
def spider():
url = "http://bj.grfy.net/"
proxies = {"http": "http://172.17.18.80:8080", "https": "https://172.17.18.80:8080"}
r = requests.get(url, proxies=proxies)
html = r.content
soup = BeautifulSoup(html, "lxml")
divs = soup.find_all("div", class_="content")
print len(divs)
print soup
if __name__ == "__main__":
os.system("pause")HTTP代理神器FidderFiddler不但能截获各种浏览器发出的HTTP请求, 也可以截获各种智能手机发出的HTTP/HTTPS请求。 Fiddler能捕获IOS设备发出的请求,比如IPhone, IPad, MacBook. 等等苹果的设备。 同理,也可以截获Andriod,Windows Phone的等设备发出的HTTP/HTTPS。工作原理:Fiddler 是以代理web服务器的形式工作的,它使用代理地址:127.0.0.1,端口:8888。Fiddler抓取HTTPS设置:启动Fiddler,打开菜单栏中的 Tools & Fiddler Options,打开“Fiddler Options”对话框。对Fiddler进行设置:打开工具栏-&Tools-&Fiddler Options-&HTTPS选中Capture HTTPS CONNECTs,因为我们要用Fiddler获取手机客户端发出的HTTPS请求,所以中间的下拉菜单中选中from remote clients only。选中下方Ignore server certificate errors.配置Fiddler允许远程连接:Fiddler 主菜单 Tools -& Fiddler Options…-& Connections页签,选中Allow remote computers to connect。重启Fidler(这一步很重要,必须做)。Fiddler 如何捕获Chrome的会话:switchyomega安装插件翻墙工具:
打开网址:Fiddler 如何捕获Firefox的会话能支持HTTP代理的任意程序的数据包都能被Fiddler嗅探到,Fiddler的运行机制其实就是本机上监听8888端口的HTTP代理。 Fiddler2启动的时候默认IE的代理设为了127.0.0.1:8888,而其他浏览器是需要手动设置的,所以将Firefox的代理改为127.0.0.1:8888就可以监听数据了。 Firefox 上通过如下步骤设置代理 点击: Tools -& Options, 在Options 对话框上点击Advanced tab - & network tab -& setting.Fiddler如何捕获HTTPS会话默认下,Fiddler不会捕获HTTPS会话,需要你设置下, 打开Fiddler Tool-&Fiddler Options-&HTTPS tab选中checkbox, 弹出如下的对话框,点击"YES"点击"Yes" 后,就设置好了。Fiddler的基本界面特别注意: 遇到这个Click请点击Click Fiddler强大的Script系统Fiddler包含了一个强大的基于事件脚本的子系统,并且能使用.net语言进行扩展。 官方的帮助文档: 首先先安装SyntaxView插件,Inspectors tab-&Get SyntaxView tab-&Download and Install SyntaxView Now... 如下图安装成功后Fiddler 就会多了一个Fiddler Script tab,如下图:在里面我们就可以编写脚本了, 看个实例让所有cnblogs的会话都显示红色。 把这段脚本放在OnBeforeRequest(oSession: Session) 方法下,并且点击"Save script"if (oSession.HostnameIs("www.cnblogs.com")) {
  oSession["ui-color"] = "red";
}这样所有的cnblogs的会话都会显示红色。HTTP协议介绍设计HTTP(HyperText Transfer Protocol)是为了提供一种发布和接收HTML(HyperText Markup Language)页面的方法。Http两部分组成:请求、响应。客户端请求消息:客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。服务器响应消息:HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。提出一个问题?服务器和客户端的交互仅限于请求/响应过程,结束之后便断开, 在下一次请求服务器会认为新的客户端;为了维护他们之间的链接,让服务器知道这是前一个用户发送的请求,必须在一个地方保存客户端的信息,Cookie通过在客户端记录信息确定用户身份。 Session通过在服务器端记录信息确定用户身份。HTTP 请求请求方法根据HTTP标准,HTTP请求可以使用多种请求方法。HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。序号方法描述1GET请求指定的页面信息,并返回实体主体。2HEAD类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头3POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。4PUT从客户端向服务器传送的数据取代指定的文档的内容。5DELETE请求服务器删除指定的页面。6CONNECTHTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。7OPTIONS允许客户端查看服务器的性能。8TRACE回显服务器收到的请求,主要用于测试或诊断。GET和POST方法区别归纳如下几点:1. GET是从服务器上获取数据,POST是向服务器传送数据。2. GET请求参数显示,都显示在浏览器网址上,POST请求参数在请求体当中,消息长度没有限制而且以隐式的方式进行发送3. 尽量避免使用Get方式提交表单,因为有可能会导致安全问题。 比如说在登陆表单中用Get方式,用户输入的用户名和密码将在地址栏中暴露无遗。 但是在分页程序中,用Get方式就比用Post好。URL概述统一资源定位符(URL,英语 Uniform / Universal Resource Locator的缩写)是用于完整地描述Internet上网页和其他资源的地址的一种标识方法。URL格式:基本格式如下 schema://host[:port#]/path/…/[?query-string][#anchor]1. schema 协议(例如:http, https, ftp)2. host 服务器的IP地址或者域名3. port# 服务器的端口(如果是走协议默认端口,缺省端口80)4. path 访问资源的路径5. query-string 参数,发送给http服务器的数据6. anchor- 锚(跳转到网页的指定锚点位置)例子:http://www.sina.com.cn/http://192.168.0.116:8080/index.jsphttp://item.jd.com/.html#product-detailhttp://www.website.com/test/test.aspx?name=sv&x=true#stuff一个URL的请求过程:当你在浏览器输入URL http://www.website.com 的时候,浏览器发送一个Request去获取 http://www. website.com的html. 服务器把Response发送回给浏览器. 浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如图片,CSS文件,JS文件。 浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。 当所有的文件都下载成功后, 网页就被显示出来了。常用的请求报头Host:Host初始URL中的主机和端口,用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的Connection:表示客户端与服务连接类型;1. client 发起一个包含Connection:keep-alive的请求2. server收到请求后如果server支持keepalive回复一个包含Connection:keep-alive的响应不关闭连接,否则回复一个包含Connection:close的响应关闭连接。3. 如果client收到包含Connection:keep-alive的响应,向同一个连接发送下一个请求,直到一方主动关闭连接。 Keep-alive在很多情况下能够重用连接,减少资源消耗,缩短响应时间HTTPAccept:表示浏览器支持的 MIME 类型MIME的英文全称是 Multipurpose Internet Mail Extensions(多用途互联网邮件扩展)eg:Accept:image/gif,表明客户端希望接受GIF图象格式的资源;Accept:text/html,表明客户端希望接受html文本。Accept: text/html,application/xhtml+xml,application/q=0.9,*/*;q=0.8意思:浏览器支持的 MIME 类型分别是 text/html、application/xhtml+xml、application/xml 和 */*,优先顺序是它们从左到右的排列顺序。Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;Application:用于传输应用程序数据或者二进制数据;设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开Mime类型扩展名text/html.htm .html *.shtmltext/plaintext/html是以html的形式输出,比如&input type="text"/&就会在页面上显示一个文本框,而以plain形式就会在页面上原样显示这段代码application/xhtml+xml.xhtml .xmltext/css*.cssapplication/msexcel.xls .xlaapplication/msword.doc .dotapplication/octet-stream*.exeapplication/pdf*.pdf..........q是权重系数,范围 0 =& q &= 1,q 值越大,请求越倾向于获得其“;”之前的类型表示的内容,若没有指定 q 值越大,请求越倾向于获得其“,则默认为1,若被赋值为0,则用于提醒服务器哪些是浏览器不接受的内容类型。Content-Type:POST 提交,application/x-www-form-urlencoded 提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。User-Agent: 浏览器类型Referer: 请求来自哪个页面,用户是从该 Referer URL页面访问当前请求的页面。Accept-Encoding:浏览器支持的压缩编码类型,比如gzip,支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间eg:Accept-Encoding:q=1.0, q=0.5, *;q=0 // 按顺序支持 gzip , identity如果有多个Encoding同时匹配, 按照q值顺序排列如果请求消息中没有设置这个域,服务器假定客户端对各种内容编码都可以接受。Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。eg:Accept-Language:zh-cn如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。Accept-Charset:浏览器可接受的字符集,用于指定客户端接受的字符集eg:Accept-Charset:iso-8859-1,gb2312ISO8859-1,通常叫做Latin-1。Latin-1包括了书写所有西方欧洲语言不可缺少的附加字符;gb2312是标准中文字符集;UTF-8 是 UNICODE 的一种变长字符编码,可以解决多种语言文本显示问题,从而实现应用国际化和本地化。如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。HTTP 响应掌握常用的响应状态码服务器上每一个HTTP 应答对象response包含一个数字"状态码"。有时状态码指出服务器无法完成请求。默认的处理器会为你处理一部分这种应答。例如:假如response是一个"重定向",需要客户端从别的地址获取文档,urllib2将为你处理。其他不能处理的,urlopen会产生一个HTTPError。典型的错误包含"404"(页面无法找到),"403"(请求禁止),和"401"(带验证请求)。HTTP状态码表示HTTP协议所返回的响应的状态。比如客户端向服务器发送请求,如果成功地获得请求的资源,则返回的状态码为200,表示响应成功。如果请求的资源不存在, 则通常返回404错误。 HTTP响应状态码通常分为5种类型,分别以1~5五个数字开头,由3位整数组成,第一个数字定义了响应的类别:分类分类描述1**信息,服务器收到请求,需要请求者继续执行操作2**成功,操作被成功接收并处理3**重定向,需要进一步的操作以完成请求4**客户端错误,请求包含语法错误或无法完成请求5**服务器错误,服务器在处理请求的过程中发生了错误最常用的响应状态码200 (OK): 请求成功,找到了该资源,并且一切正常。处理方式:获得响应的内容,进行处理 201 请求完成,结果是创建了新资源。新创建资源的URI可在响应的实体中得到
处理方式:爬虫中不会遇到 202 请求被接受,但处理尚未完成
处理方式:阻塞等待 204 服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。
处理方式:丢弃300 该状态码不被HTTP/1.0的应用程序直接使用, 只是作为3XX类型回应的默认解释。存在多个可用的被请求资源。
处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃301 (Moved Permanently): 请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。处理方式:重定向到分配的URL302 (Found): 类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。处理方式:重定向到临时的URL 304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。处理方式:丢弃 400 (Bad Request): 请求出现语法错误。非法请求
处理方式:丢弃 401 未授权
处理方式:丢弃 403 (FORBIDDEN): 客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。禁止访问
处理方式:丢弃 404 (NOT FOUND): 在指定的位置不存在所申请的资源。没有找到 。
处理方式:丢弃 5XX 回应代码以“5”开头的状态码表示服务器端发现自己出现错误,不能继续执行请求
处理方式:丢弃500 (Internal Server Error): 服务器遇到了意料不到的情况,不能完成客户的请求503 (Service Unavailable): 服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头常用的响应报头(了解)Location:表示客户应当到哪里去提取文档,用于重定向接受者到一个新的位置Server:服务器名字,包含了服务器用来处理请求的软件信息eg: Server响应报头域的一个例子:Server:Apache-Coyote/1.1Set-Cookie:设置和页面关联的Cookie。例如:前一个 cookie 被存入浏览器并且浏览器试图请求 http://www.ibm.com/foo/index.html 时Set-Cookie:customer= path=/ domain=.ibm. expires= Wednesday, 19-OCT-05 23:12:40 GMT;Set-Cookie的每个属性解释如下:Customer=huangxp 一个"名称=值"对,把名称customer设置为值"huangxp",这个属性在Cookie中必须有。path=/foo 服务器路径。domain=.ibm.com 指定cookie 的域名。expires= Wednesday, 19-OCT-05 23:12:40 GMT 指定cookie 失效的时间使用 Urllib2库urllib2是python2.7自带的模块(不需要下载),它支持多种网络协议,比如 FTP、HTTP、HTTPS等。 urllib2在python3.x中被改为urllib.request利用urllib2提供了一个接口 urlopen函数urllib2 官方文档 :urlopen(url, data, timeout,....)(1)第一个参数url即为URL,第一个参数URL是必须要传送的(2)第二个参数data是访问URL时要传送的数据,data默认为空None(3)第三个timeout是设置超时时间,timeout默认为 60s(socket._GLOBAL_DEFAULT_TIMEOUT)GET请求方式以传智播客官方网站 http://www.itcast.cnimport urllib2
response = urllib2.urlopen('http://www.itcast.cn/')
data = response.read()
print data
print response.code保存成 demo.py,进入该文件的目录,执行如下命令查看运行结果: python demo.py如果我想添加 Header信息怎么办? 利用 urllib2.Request类利用urllib2.Request方法,可以用来构造一个Http请求消息help(urllib2.Request)正则:headers 转dict
^(.*):\s(.*)$
"\1":"\2",# -*- coding: utf-8 -*-
import urllib2
get_headers={
'Host': 'www.itcast.cn',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0. Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/q=0.9,image/webp,*/*;q=0.8',
#此处是压缩算法;不便于查看,要做解压
#'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'zh-CN,q=0.8',
'Cookie': 'pgv_pvi=; tencentSig=; IESESSION= pgv_si=s; CNZZDATA4617777=cnzz_eid%3Dntime%3D; _qdda=3-1.1; _qddab=3-dyl6uh.ireawgo0; _qddamta_-0'
request = urllib2.Request("http://www.itcast.cn/",headers=get_headers)
#request.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0. Safari/537.36')
response = urllib2.urlopen(request)
print response.code
data = response.read()
print data提问:为什么这两种写法都对?一个headers没写,另一个写了都好使; 原因是web服务器能够理解请求数据,并且没有做验证机制POST请求方式抓取拉钩招聘信息:# -*- coding: utf-8 -*-
import urllib2
import urllib
proxy_handler = urllib2.ProxyHandler({"http" : 'http://192.168.17.1:8888'})
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)
output = open('lagou.json', 'w')
for page in range(1,Sum+1):
formdata = 'first=false&pn='+str(page)+'&kd='
print '运行到第 (%2d) 页面' %(page)
send_headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0. Safari/537.36',
'Content-Type': 'application/x-www-form- charset=UTF-8',
'Accept': 'application/json, text/javascript, */*; q=0.01',
' X-Requested-With': 'XMLHttpRequest'
request =urllib2.Request('http://www.lagou.com/jobs/positionAjax.json?px=new&needAddtionalResult=false',headers=send_headers)
#request.add_header('X-Requested-With','XMLHttpRequest')
#request.headers=send_headers
request.add_data(formdata)
print request.get_data()
response = urllib2.urlopen(request)
print response.code
resHtml =response.read()
#print resHtml
output.write(resHtml+'\n')
output.close()
print '-'*4 + 'end'+'-'*4提出一个问题,如果要采集的是 拉钩招聘网站 北京&&朝阳区&&望京 以这个网站为例,该如何理解这个url ?http://www.lagou.com/jobs/list_?px=default&city=%E5%8C%97%E4%BA%AC&district=%E6%9C%9D%E9%98%B3%E5%8C%BA&bizArea=%E6%9C%9B%E4%BA%AC#filterBox# -*- coding: utf-8 -*-
import urllib2
import urllib
'city':'北京',
'district':'朝阳区',
'bizArea':'望京'
print urllib.urlencode(query)
values = {
'first':'false',
'pn':str(page),
'kd':'后端开发',
formdata = urllib.urlencode(values)
print formdata小结Content-Length: 是指报头Header以外的内容长度,指 表单数据长度X-Requested-With: XMLHttpRequest :表示Ajax异步请求Content-Type: application/x-www-form-urlencoded :表示:提交的表单数据 会按照name/value 值对 形式进行编码例如:name1=value1&name2=value2... 。name 和 value 都进行了 URL 编码(utf-8、gb2312)作业常用的请求报头(Header、Content-Type)、响应报头常用请求方式(GET、POST)gzip、deflate压缩网页编码格式和自动识别fidder工具使用urllib2、urllibHTTP代理URL和URI的区别URL:统一资源定位符(uniform resource location);平时上网时在 IE 浏览器中输入的那个地址就是 URL。比如:网易 http://www.163.com 就是一个URL 。URI:统一资源标识符(uniform resource identifier)。Web 上可用的每种资源 - HTML 文档、图像、视频片段、程序, 由一个通过通用资源标志符 (Universal Resource Identifier, 简称 "URI") 进行定位。URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URI 是个纯粹的语法结构,用于指定标识web资源的字符串的各个不同部分,URL 是URI的一个特例,它包含定位web资源的足够信息。URL 是 URI 的一个子集常见的加密、解密1) MD5/SHA (单向密散列算法(Hash函数)) MessageDigest是一个数据的数字指纹.即对一个任意长度的数据进行计算,产生一个唯一指纹号. MessageDigest的特性: A) 两个不同的数据,难以生成相同的指纹号 B) 对于指定的指纹号,难以逆向计算出原始数据 代表:MD5/SHA2) DES、AES、TEA(对称加密算法) 单密钥算法,是信息的发送方采用密钥A进行数据加密,信息的接收方采用同一个密钥A进行数据解密. 单密钥算法是一个对称算法. 缺点:由于采用同一个密钥进行加密解密,在多用户的情况下,密钥保管的安全性是一个问题. 代表:DES3) RSA(非对称算法) RSA 是一种非对称加解密算法。 RSA is named from the initials of the authors, Ron Rivest, Adi Shamir, and Leonard Adleman,who first published the algorithm.RSA 与 DSA 都是非对称加密算法。其中RSA的安全性是基于极其困难的大整数的分解(两个素数的乘积);DSA 的安全性 是基于整数有限域离散对数难题。基本上可以认为相同密钥长度的 RSA 算法与 DSA 算法安全性相当。 公钥用于加密,它是向所有人公开的;私钥用于解密,只有密文的接收者持有。 适用OPENSSL 适用RSA 的命令如下: 生成一个密钥(私钥) [root@hunterfu ~]# openssl genrsa -out private.key 1024 注意: 需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密,后面的1024是生成 密钥的长度. 通过密钥文件private.key 提取公钥[root@hunterfu ~]# openssl rsa -in private.key -pubout -out pub.key使用公钥加密信息[root@hunterfu ~]# echo -n "123456" | openssl rsautl -encrypt -inkey pub.key -pubin &encode.result使用私钥解密信息[root@hunterfu ~]#cat encode.result | openssl rsautl -decrypt -inkey private.key1234564) DSA (Digital Signature Algorithm)(数字签名算法)(非对称加密) DSA 一般用于数字签名和认证。 DSA是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。 DSA是基于整数有限域离散对数难题的,其安全性与RSA相比差不多。 在DSA数字签名和认证中,发送者使用自己的私钥对文件或消息进行签名,接受者收到消息后使用发送者的公钥 来验证签名的真实性。DSA只是一种算法,和RSA不同之处在于它不能用作加密和解密,也不能进行密钥交换, 只用于签名,它比RSA要快很多. 生成一个密钥(私钥)[root@hunterfu ~]# openssl dsaparam -out dsaparam.pem 1024[root@hunterfu ~]# openssl gendsa -out privkey.pem dsaparam.pem生成公钥[root@hunterfu ~]# openssl dsa -in privkey.pem -out pubkey.pem -pubout [root@hunterfu ~]# rm -fr dsaparam.pem# rm -fr == rm -rf == rm -r -f没区别。使用私钥签名[root@hunterfu ~]# echo -n "123456" | openssl dgst -dss1 -sign privkey.pem & sign.result使用公钥验证[root@hunterfu ~]# echo -n "123456" | openssl dgst -dss1 -verify pubkey.pem -signature sign.result爬虫入门基础篇数据格式描述设计目标XMLExtensible Markup Language (可扩展标记语言)被设计为传输和存储数据,其焦点是数据的内容HTMLHyperText Markup Language(超文本标记语言)显示数据以及如何更好显示数据HTML DOMHTML Document Object Model(文档对象模型)通过 JavaScript,您可以重构整个HTML文档。您可以添加、移除、改变或重排页面上的项目。要改变页面的某个东西,JavaScript就需要对HTML文档中所有元素进行访问的入口。XML 示例&?xml version="1.0" encoding="utf-8"?&
&bookstore&
&book category="cooking"&
&title lang="en"&Everyday Italian&/title&
&author&Giada De Laurentiis&/author&
&year&2005&/year&
&price&30.00&/price&
&book category="children"&
&title lang="en"&Harry Potter&/title&
&author&J K. Rowling&/author&
&year&2005&/year&
&price&29.99&/price&
&book category="web"&
&title lang="en"&XQuery Kick Start&/title&
&author&James McGovern&/author&
&author&Per Bothner&/author&
&author&Kurt Cagle&/author&
&author&James Linn&/author&
&author&Vaidyanathan Nagarajan&/author&
&year&2003&/year&
&price&49.99&/price&
&book category="web" cover="paperback"&
&title lang="en"&Learning XML&/title&
&author&Erik T. Ray&/author&
&year&2003&/year&
&price&39.95&/price&
&/bookstore&XML DOM 定义访问和操作XML文档的标准方法。 DOM 将 XML 文档作为一个树形结构,而树叶被定义为节点。HTML DOM 示例HTML DOM 定义了访问和操作 HTML 文档的标准方法。 DOM 以树结构表达 HTML 文档。页面解析之数据提取一般来讲对我们而言,需要抓取的是某个网站或者某个应用的内容,提取有用的价值,内容一般分为两部分,非结构化的文本,或结构化的文本。结构化的数据:JSON、XML非结构化的数据:HTML文本(包含JavaScript代码)HTML文本(包含JavaScript代码)是最常见的数据格式,理应属于结构化的文本组织,但因为一般我们需要的关键信息并非直接可以得到,需要进行对HTML的解析查找,甚至一些字符串操作才能得到,所以还是归类于非结构化的数据处理中。把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。常见解析方式如下:XPath、CSS选择器、正则表达式。一段文本例如一篇文章,或者一句话,我们的初衷是提取有效信息,所以如果是滞后处理,可以直接存储,如果是需要实时提取有用信息,常见的处理方式如下:分词 根据抓取的网站类型,使用不同词库,进行基本的分词,然后变成词频统计,类似于向量的表示,词为方向,词频为长度。NLP 自然语言处理,进行语义分析,用结果表示,例如正负面等。非结构化数据之XPathXPath 语言:XPath(XML Path Language)是XML路径语言,它是一种用来定位XML文档中某部分位置的语言。将HTML转换成XML文档之后,用XPath查找HTML节点或元素比如用“/”来作为上下层级间的分隔,第一个“/”表示文档的根节点(注意,不是指文档最外层的tag节点,而是指文档本身)。比如对于一个HTML文件来说,最外层的节点应该是"/html"。XPath开发工具:开源的XPath表达式编辑工具:XMLQuire(XML格式文件可用)、chrome插件 XPath Helperfirefox插件 XPath CheckerXPath语法参考文档:XPath语法XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。&?xml version="1.0" encoding="ISO-8859-1"?&
&bookstore&
&title lang="eng"&Harry Potter&/title&
&price&29.99&/price&
&title lang="eng"&Learning XML&/title&
&price&39.95&/price&
&/bookstore&选取节点 XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。下面列出了最有用的路径表达式:表达式描述/从根节点选取。nodename选取此节点的所有子节点。//从当前节点 选择 所有匹配文档中的节点.选取当前节点。..选取当前节点的父节点。@选取属性。在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:路径表达式结果/bookstore选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!bookstore选取 bookstore 元素的所有子节点。默认从根节点选取bookstore/book选取属于 bookstore 的子元素的所有 book 元素。//book选取所有 book 子元素,而不管它们在文档中的位置。//book/./title选取所有 book 子元素,从当前节点查找title节点//price/..选取所有 book 子元素,从当前节点查找父节点bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。//@lang选取名为 lang 的所有属性。谓语条件(Predicates)谓语用来查找某个特定的信息或者包含某个指定的值的节点。所谓"谓语条件",就是对路径表达式的附加条件谓语是被嵌在方括号中,都写在方括号"[]"中,表示对节点进行进一步的筛选。在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:路径表达式结果/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。/bookstore/book[position()&3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素。//title[@lang]选取所有拥有名为 lang 的属性的 title 元素。//title[@lang=’eng’]选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。//book[price]选取所有 book 元素,且被选中的book元素必须带有price子元素/bookstore/book[price&35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。/bookstore/book[price&35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00选取未知节点:XPath 通配符可用来选取未知的 XML 元素。通配符描述*匹配任何元素节点。@*匹配任何属性节点。在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:路径表达式结果/bookstore/*选取 bookstore 元素的所有子元素。//*选取文档中的所有元素。//title[@*]选取所有带有属性的 title 元素。选取若干路径: 通过在路径表达式中使用“|”运算符,您可以选取若干个路径。在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:路径表达式结果//book/title | //book/price选取 book 元素的所有 title 和 price 元素。//title | //price选取文档中的所有 title 和 price 元素。/bookstore/book/title | //price选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。XPath 高级用法模糊查询 contains目前许多web框架,都是动态生成界面的元素id,因此在每次操作相同界面时,ID都是变化的,这样为自动化测试造成了一定的影响。&div class="eleWrapper" title="请输入用户名"&
&input type="text" class="textfield" name="ID9sLJQnkQyLGLhYShhlJ6gPzHLgvhpKpLzp2Tyh4hyb1b4pnvzxFR!-" id="nt8" /&
&/div&解决方法 使用xpath的匹配功能,//input[contains(@id,'nt')]测试使用的XML
&Person ID="1001" &
&Name lang="zh-cn" &张城斌&/Name&
&Email xmlns="www.quicklearn.cn" &
&Blog&http://cbcye.cnblogs.com&/Blog&
&Person ID="1002" &
&Name lang="en" &Gary Zhang&/Name&
&Email xmlns="www.quicklearn.cn" & &/Email&
&Blog&http://www.quicklearn.cn&/Blog&
&/Root&1.查询所有Blog节点值中带有 cn 字符串的Person节点。Xpath表达式:/Root//Person[contains(Blog,'cn')]2.查询所有Blog节点值中带有 cn 字符串并且属性ID值中有01的Person节点。Xpath表达式:/Root//Person[contains(Blog,'cn') and contains(@ID,'01')]学习笔记1.依靠自己的属性,文本定位
//td[text()='Data Import']
//div[contains(@class,'cux-rightArrowIcon-on')]
//a[text()='马上注册']
//input[@type='radio' and @value='1']
//span[@name='bruce'][text()='bruce1'][1]
//span[@id='bruce1' or text()='bruce2']
//span[text()='bruce1' and text()='bruce2']
2.依靠父节点定位
//div[@class='x-grid-col-name x-grid-cell-inner']/div
//div[@id='dynamicGridTestInstanceformclearuxformdiv']/div
//div[@id='test']/input
3.依靠子节点定位
//div[div[@id='navigation']]
//div[div[@name='listType']]
//div[p[@name='testname']]
//div[div[@name='listType']]//img
//td[a//font[contains(text(),'seleleium2从零开始 视屏')]]//input[@type='checkbox']
5.进阶部分
//input[@id='123']/following-sibling::input
找下一个兄弟节点
//input[@id='123']/preceding-sibling::span
上一个兄弟节点
//input[starts-with(@id,'123')]
以什么开头
//span[not(contains(text(),'xpath'))]
不包含xpath字段的span
//div/input[2]
//div[@id='position']/span[3]
//div[@id='position']/span[position()=3]
//div[@id='position']/span[position()&3]
//div[@id='position']/span[position()&3]
//div[@id='position']/span[last()]
//div[@id='position']/span[last()-1]
7.substring 截取判断
&div data-for="result" id="swfEveryCookieWrap"&&/div&
//*[substring(@id,4,5)='Every']/@id
截取该属性 定位3,取长度5的字符
//*[substring(@id,4)='EveryCookieWrap']
截取该属性从定位3 到最后的字符
//*[substring-before(@id,'C')='swfEvery']/@id
属性 'C'之前的字符匹配
//*[substring-after(@id,'C')='ookieWrap']/@id
属性'C之后的字符匹配
//span[@*='bruce']
//*[@name='bruce']
//div[span[text()='+++current node']]/parent::div
//div[span[text()='+++current node']]/ancestor::div
找祖先节点
10.孙子节点
//div[span[text()='current note']]/descendant::div/span[text()='123']
//div[span[text()='current note']]//div/span[text()='123']
两个表达的意思一样
11.following pre
https://www.baidu.com/s?wd=xpath&pn=10&oq=xpath&ie=utf-8&rsv_idx=1&rsv_pq=df1c&rsv_t=7dccXo734hMJVeb6AVGfAFXQST0DrOW%2BM8GijQ8m5rVN2R4J3gU
//span[@class="fk fk_cur"]/../following::a
往下的所有a
//span[@class="fk fk_cur"]/../preceding::a[1]
往上的所有a
xpath提取多个标签下的text
在写爬虫的时候,经常会使用xpath进行数据的提取,对于如下的代码:
&div id="test1"&大家好!&/div&
使用xpath提取是非常方便的。假设网页的源代码在selector中:
data = selector.xpath('//div[@id="test1"]/text()').extract()[0]
就可以把“大家好!”提取到data变量中去。
然而如果遇到下面这段代码呢?
&div id="test2"&美女,&font color=red&你的微信是多少?&/font&&div&
如果使用:
data = selector.xpath('//div[@id="test2"]/text()').extract()[0]
只能提取到“美女,”;
如果使用:
data = selector.xpath('//div[@id="test2"]/font/text()').extract()[0]
又只能提取到“你的微信是多少?”
可是我本意是想把“美女,你的微信是多少?”这一整个句子提取出来。
&div id="test3"&我左青龙,&span id="tiger"&右白虎,&ul&上朱雀,&li&下玄武。&/li&&/ul&老牛在当中,&/span&龙头在胸口。&div&
而且内部的标签还不固定,如果我有一百段这样类似的html代码,又如何使用xpath表达式,以最快最方便的方式提取出来?
使用xpath的string(.)
以第三段代码为例:
data = selector.xpath('//div[@id="test3"]')
info = data.xpath('string(.)').extract()[0]
这样,就可以把“我左青龙,右白虎,上朱雀,下玄武。老牛在当中,龙头在胸口”整个句子提取出来,赋值给info变量。非结构化数据之lxml库lxml 是一种使用 Python 编写的库,可以迅速、灵活地处理 XML ,支持 XPath (XML Path Language)lxml python 官方文档 学习目的:利用上节课学习的XPath语法,来快速的定位 特定元素以及节点信息,目的是 提取出 HTML、XML 目标数据如何安装Ubuntu :sudo apt-get install libxml2-dev libxslt1-dev python-devsudo apt-get install zlib1g-devsudo apt-get install libevent-devsudo pip install lxml //利用 pip 安装即可Windows:http://blog.csdn.net/g1apassz/article/details/http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml初步使用首先我们利用lxml来解析 HTML 代码,先来一个小例子来感受一下它的基本用法。使用 lxml 的 etree 库,然后利用 etree.HTML 初始化,然后我们将其打印出来。from lxml import etree
text = '''
&li class="item-0"&&a href="link1.html"&first item&/a&&/li&
&li class="item-1"&&a href="link2.html"&second item&/a&&/li&
&li class="item-inactive"&&a href="link3.html"&&span class="bold"&third item&/span&&/a&&/li&
&li class="item-1"&&a href="link4.html"&fourth item&/a&&/li&
&li class="item-0"&&a href="link5.html"&fifth item&/a&
#Parses an HTML document from a string
html = etree.HTML(text)
#Serialize an element to an encoded string representation of its XML tree
result = etree.tostring(html)
print result所以输出结果是这样的
&html&&body&&div&
&li class="item-0"&&a href="link1.html"&first item&/a&&/li&
&li class="item-1"&&a href="link2.html"&second item&/a&&/li&
&li class="item-inactive"&&a href="link3.html"&&span class="bold"&third item&/span&&/a&&/li&
&li class="item-1"&&a href="link4.html"&fourth item&/a&&/li&
&li class="item-0"&&a href="link5.html"&fifth item&/a&
&/li&&/ul&
&/body&&/html&不仅补全了 li 标签,还添加了 body,html 标签。XPath实例测试(1)获取所有的 &li& 标签print type(html)result = html.xpath('//li')print resultprint len(result)print type(result)print type(result[0])运行结果&type 'lxml.etree._ElementTree'&[&Element li at 0x&, &Element li at 0x&, &Element li at 0x&, &Element li at 0x&, &Element li at 0x&]5&type 'list'&&type 'lxml.etree._Element'&可见,每个元素都是 Element 类型;是一个个的标签元素,类似现在的实例&Element li at 0x& Element类型代表的就是&li class="item-0"&&a href="link1.html"&first item&/a&&/li&[注意]Element类型是一种灵活的容器对象,用于在内存中存储结构化数据。每个element对象都具有以下属性:  1. tag:string对象,标签,用于标识该元素表示哪种数据(即元素类型)。  2. attrib:dictionary对象,表示附有的属性。  3. text:string对象,表示element的内容。  4. tail:string对象,表示element闭合之后的尾迹。实例&tag attrib1=1&text&/tag&tail1
4result[0].tagresult[0].textresult[0].tailresult[0].attrib(2)获取 &li& 标签的所有 classhtml.xpath('//li/@class')运行结果:['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0'](3)获取 &li& 标签下属性 href 为 link1.html 的 &a& 标签html.xpath('//li/a[@href="link1.html"]')运行结果:[&Element a at 0x10ffaae18&](4)获取 &li& 标签下的所有 &span& 标签注意这么写是不对的html.xpath('//li/span')因为 / 是用来获取子元素的,而 &span& 并不是 &li& 的子元素,所以,要用双斜杠html.xpath('//li//span')运行结果:[&Element span at 0x10d698e18&](5)获取 &li& 标签下的所有 class,不包括 &li&html.xpath('//li/a//@class')运行结果:['blod'](6)获取最后一个 &li& 的&a& 的 hrefhtml.xpath('//li[last()]/a/@href')运行结果:['link5.html'](7)获取 class 为 bold 的标签名result = html.xpath('//*[@class="bold"]')print result[0].tag运行结果:span实战项目from lxml import etree
import urllib2
import urllib
import json
request = urllib2.Request('http://hr.tencent.com/position.php?&start=10#a')
response =urllib2.urlopen(request)
resHtml = response.read()
output =open('tencent.json','w')
html = etree.HTML(resHtml)
result = html.xpath('//tr[@class="odd"] | //tr[@class="even"]')
for site in result:
name = site.xpath('./td[1]/a')[0].text
detailLink = site.xpath('./td[1]/a')[0].attrib['href']
catalog = site.xpath('./td[2]')[0].text
recruitNumber = site.xpath('./td[3]')[0].text
workLocation = site.xpath('./td[4]')[0].text
publishTime = site.xpath('./td[5]')[0].text
print type(name)
print name,detailLink,catalog,recruitNumber,workLocation,publishTime
item['name']=name
item['detailLink']=detailLink
item['catalog']=catalog
item['recruitNumber']=recruitNumber
item['publishTime']=publishTime
line = json.dumps(item,ensure_ascii=False) + '\n'
print line
output.write(line.encode('utf-8'))
output.close()(1)练习一下lxml、etree、xpath的整个的操作(2)试试上节课XPath的语法以及Html,自己动手实践非结构化数据之CSS Selector(CSS 选择器)CSS(即层叠样式表Cascading Stylesheet) Selector来定位(locate)页面上的元素(Elements)。Selenium官网的Document里极力推荐使用CSS locator,而不是XPath来定位元素,原因是CSS locator比XPath locator速度快.Beautiful Soup支持从HTML或XML文件中提取数据的Python库。支持Python标准库中的HTML解析器。还支持一些第三方的解析器lxml, 使用的是 Xpath 语法,推荐安装。Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了Beautiful Soup4 安装官方文档链接: 可以利用 pip来安装:pip install beautifulsoup4安装解析器(上节课已经安装过)Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml .根据操作系统不同,可以选择下列方法来安装lxml:另一个可供选择的解析器是纯Python实现的 html5lib , html5lib的解析方式与浏览器相同,可以选择下列方法来安装html5lib: pip install html5lib下表列出了主要的解析器:解析器使用方法优势劣势Python标准库BeautifulSoup(markup, "html.parser")Python的内置标准库;执行速度适中;文档容错能力强Python 2.7.3 or 3.2.2前 的版本中文档容错能力差lxml HTML 解析器BeautifulSoup(markup, "lxml")速度快;文档容错能力强 ;需要安装C语言库lxml XML 解析器BeautifulSoup(markup, ["lxml-xml"]) BeautifulSoup(markup, "xml")速度快;唯一支持XML的解析器需要安装C语言库html5libBeautifulSoup(markup, "html5lib")最好的容错性;以浏览器的方式解析文档;生成HTML5格式的文档速度慢;不依赖外部扩展推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定.html_doc = """
&html&&head&&title&The Dormouse's story&/title&&/head&
&p class="title"&&b&The Dormouse's story&/b&&/p&
&p class="story"&Once upon a time there were
and their names were
&a href="http://example.com/elsie" class="sister" id="link1"&Elsie&/a&,
&a href="http://example.com/lacie" class="sister" id="link2"&Lacie&/a& and
&a href="http://example.com/tillie" class="sister" id="link3"&Tillie&/a&;
and they lived at the bottom of a well.&/p&
&p class="story"&...&/p&
"""使用BeautifulSoup解析这段代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出:from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc,'lxml')下面我们来打印一下 soup 对象的内容print soup格式化输出soup 对象print(soup.prettify())CSS选择器在写 CSS 时:标签名不加任何修饰。类名前加点。id名前加“#”。 利用类似的方法来筛选元素,用到的方法是 soup.select(),返回类型是 list通过标签名查找print soup.select('title')
#[&title&The Dormouse's story&/title&]
print soup.select('a')
#[&a class="sister" href="http://example.com/elsie" id="link1"&&/a&, &a class="sister" href="http://example.com/lacie" id="link2"&Lacie&/a&, &a class="sister" href="http://example.com/tillie" id="link3"&Tillie&/a&]
print soup.select('b')
#[&b&The Dormouse's story&/b&]通过类名查找print soup.select('.sister')
#[&a class="sister" href="http://example.com/elsie" id="link1"&&/a&, &a class="sister" href="http://example.com/lacie" id="link2"&Lacie&/a&, &a class="sister" href="http://example.com/tillie" id="link3"&Tillie&/a&]通过 id 名查找print soup.select('#link1')
#[&a class="sister" href="http://example.com/elsie" id="link1"&&/a&]直接子标签查找print soup.select("head & title")
#[&title&The Dormouse's story&/title&]组合查找组合查找即标签名与类名、id名进行的组合原理是一样的,例如查找 p 标签中,id 等于 link1的内容,属性 和 标签 不属于 同一节点
二者需要用
空格分开print soup.select('p #link1')
#[&a class="sister" href="http://example.com/elsie" id="link1"&&/a&]属性查找查找时还可以加入属性元素,属性需要用中括号括起来注意:属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到print soup.select('a[class="sister"]')
#[&a class="sister" href="http://example.com/elsie" id="link1"&&/a&, &a class="sister" href="http://example.com/lacie" id="link2"&Lacie&/a&, &a class="sister" href="http://example.com/tillie" id="link3"&Tillie&/a&]
print soup.select('a[href="http://example.com/elsie"]')
#[&a class="sister" href="http://example.com/elsie" id="link1"&&/a&]同样,属性仍然可以与上述查找方式组合。不在同一节点的使用空格隔开,在同一节点的则不用加空格print soup.select('p a[href="http://example.com/elsie"]')
#[&a class="sister" href="http://example.com/elsie" id="link1"&&/a&]以上的 select 方法返回的结果都是列表形式,可以遍历形式输出用 get_text() 方法来获取它的内容。print soup.select('title')[0].get_text()
for title in soup.select('title'):
print title.get_text()TagTag 是什么?通俗点讲就是 HTML 中的一个个标签,例如:&a class="sister" href="http://example.com/elsie" id="link1"&Elsie&/a&print type(soup.select('a')[0])输出:
bs4.element.Tag对于 Tag,它有两个重要的属性,是 name 和 attrs,下面我们分别来感受一下1. nameprint soup.name
print soup.select('a')[0].name
[document]
soup 对象本身比较特殊,它的 name 即为 [document],对于其他内部标签,输出的值便为标签本身的名称。2. attrsprint soup.select('a')[0].attrs
{'href': 'http://example.com/elsie', 'class': ['sister'], 'id': 'link1'}
在这里,我们把 soup.select('a')[0] 标签的所有属性打印输出了出来,得到的类型是一个字典。
如果我们想要单独获取某个属性,可以这样,例如我们获取它的 class 叫什么
print soup.select('a')[0].attrs['class']
['sister']实战案例from bs4 import BeautifulSoup
import urllib2
import urllib
import json
request = urllib2.Request('http://hr.tencent.com/position.php?&start=10#a')
response =urllib2.urlopen(request)
resHtml = response.read()
output =open('tencent.json','w')
html = BeautifulSoup(resHtml,'lxml')
result = html.select('tr[class="even"]')
result2 = html.select('tr[class="odd"]')
result+=result2
print len(result)
for site in result:
name = site.select('td a')[0].get_text()
detailLink = site.select('td a')[0].attrs['href']
catalog = site.select('td')[1].get_text()
recruitNumber = site.select('td')[2].get_text()
workLocation = site.select('td')[3].get_text()
publishTime = site.select('td')[4].get_text()
item['name']=name
item['detailLink']=detailLink
item['catalog']=catalog
item['recruitNumber']=recruitNumber
item['publishTime']=publishTime
line = json.dumps(item,ensure_ascii=False)
print line
output.write(line.encode('utf-8'))
output.close()正则表达式掌握了XPath、CSS选择器,为什么还要学习正则?正则表达式,用标准正则解析,一般会把HTML当做普通文本,用指定格式匹配当相关文本,适合小片段文本,或者某一串字符(比如电话号码、邮箱账户),或者HTML包含javascript的代码,无法用CSS选择器或者XPath正则表达式常见概念边界匹配^ -- 与字符串开始的地方匹配,不匹配任何字符;$ -- 与字符串结束的地方匹配,不匹配任何字符;
str = "cat abdcatdetf ios"
^cat : 验证该行以c开头紧接着是a,然后是t
ios$ : 验证该行以t结尾倒数第二个字符为a倒数第三个字符为c
^cat$: 以c开头接着是a-&t然后是行结束:只有cat三个字母的数据行
: 开头之后马上结束:空白行,不包括任何字符
: 行的开头,可以匹配任何行,因为每个行都有行开头\b -- 匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符; "er\b"可以匹配"never"中的"er",但不能匹配"verb"中的"er"。\B -- \b取非,即匹配一个非单词边界;"er\B"能匹配"verb"中的"er",但不能匹配"never"中的"er"。数量词的贪婪模式与非贪婪模式正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如: 正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。反斜杠问题与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。import re
a=re.search(r"\\","ab123bb\c")
print a.group()
a=re.search(r"\d","ab123bb\c")
print a.group()
1Python Re模块Python 自带了re模块,它提供了对正则表达式的支持。match函数:re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。下面是此函数的语法:re.match(pattern, string, flags=0)参数描述pattern这是正则表达式来进行匹配。string这是字符串,这将被搜索匹配的模式,在字符串的开头。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。匹配成功re.match方法返回一个匹配的对象,否则返回None。 我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。匹配对象的方法描述group(num=0)此方法返回整个匹配(或指定分组num)groups()此方法返回所有元组匹配的子组(空,如果没有)#!/usr/bin/python
line = "Cats are smarter than dogs"
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print "matchObj.group() : ", matchObj.group()
print "matchObj.group(1) : ", matchObj.group(1)
print "matchObj.group(2) : ", matchObj.group(2)
print "No match!!"当执行上面的代码,它产生以下结果:
matchObj.group() :
Cats are smarter than dogs
matchObj.group(1) :
matchObj.group(2) :
smarter正则表达式修饰符 - 选项标志正则表达式字面可以包含一个可选的修饰符来控制匹配的各个方面。修饰符被指定为一个可选的标志。可以使用异或提供多个修饰符(|),如先前所示,并且可以由这些中的一个来表示:修饰符描述re.I(re.IGNORECASE)使匹配对大小写不敏感re.M(MULTILINE)多行匹配,影响 ^ 和 $re.S(DOTALL)使 . 匹配包括换行在内的所有字符re.X(VERBOSE)正则表达式可以是多行,忽略空白字符,并可以加入注释findall()函数re.findall(pattern, string, flags=0)返回字符串中所有模式的非重叠的匹配,作为字符串列表。该字符串扫描左到右,并匹配返回的顺序发现默认:
pattren = "\w+"
target = "hello world\nWORLD HELLO"
re.findall(pattren,target)
['hello', 'world', 'WORLD', 'HELLO']
re.findall("world", target,re.I)
['world', 'WORLD']
re.findall("world.WORLD", target,re.S)
["world\nworld"]
re.findall("hello.*WORLD", target,re.S)
['hello world\nWORLD']
re.findall("^WORLD",target,re.M)
reStr = '''\d{3}
-\d{8}''' #号码
re.findall(reStr,"010-",re.X)
["010-"]search函数re.search 扫描整个字符串并返回第一个成功的匹配。下面是此函数语法:re.search(pattern, string, flags=0)参数描述pattern这是正则表达式来进行匹配。string这是字符串,这将被搜索到的字符串中的任何位置匹配的模式。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。匹配成功re.search方法返回一个匹配的对象,否则返回None。我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。#!/usr/bin/python
line = "Cats are smarter than dogs";
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)
if searchObj:
print "searchObj.group() : ", searchObj.group()
print "searchObj.group(1) : ", searchObj.group(1)
print "searchObj.group(2) : ", searchObj.group(2)
print "Nothing found!!"当执行上面的代码,它产生以下结果:
matchObj.group() :
Cats are smarter than dogs
matchObj.group(1) :
matchObj.group(2) :
smarterre.match与re.search的区别re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。#!/usr/bin/python
line = "Cats are smarter than dogs";
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print "match --& matchObj.group() : ", matchObj.group()
print "No match!!"
searchObj = re.search( r'dogs', line, re.M|re.I)
if searchObj:
print "search --& searchObj.group() : ", searchObj.group()
print "Nothing found!!"当执行上面的代码,产生以下结果:
No match!!
search --& matchObj.group() :
dogs搜索和替换Python 的re模块提供了re.sub用于替换字符串中的匹配项。语法:re.sub(pattern, repl, string, max=0)返回的字符串是在字符串中用 RE 最左边不重复的匹配来替换。如果模式没有发现,字符将被没有改变地返回。 可选参数 count 是模式匹配后替换的最大次数;count 必须是非负整数。缺省值是 0 表示替换所有的匹配。 实例:#!/usr/bin/python
url = "http://hr.tencent.com/position.php?&start=10"
page = re.search('start=(\d+)',url).group(1)
nexturl = re.sub(r'start=(\d+)', 'start='+str(int(page)+10), url)
print "Next Url : ", nexturl当执行上面的代码,产生以下结果:
Next Url :
http://hr.tencent.com/position.php?&start=20正则表达式语法页面解析之结构化数据结构化的数据是最好处理,一般都是类似JSON格式的字符串,直接解析JSON数据,提取JSON的关键字段即可。JSONJSON(JavaScript Object Notation) 是一种轻量级的数据交换格式;适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。Python 2.7中自带了JSON模块,直接import json就可以使用了。Json模块提供了四个功能:dumps、dump、loads、load,用于字符串 和 python数据类型间进行转换1. json.loads()实现:json字符串 转化 python的类型,返回一个python的类型从json到python的类型转化对照如下:import json
a="[1,2,3,4]"
b='{"k1":1,"k2":2}'#当字符串为字典时{}外面必须是''单引号{}里面必须是""双引号
print json.loads(a)
[1, 2, 3, 4]
print json.loads(b)
{'k2': 2, 'k1': 1}import urllib2
import json
response = urllib2.urlopen(r'http://api.douban.com/v2/book/isbn/1')
hjson = json.loads(response.read())
print hjson.keys()
print hjson['rating']
print hjson['images']['large']
print hjson['summary']2. json.dumps()实现python类型转化为json字符串,返回一个str对象从python原始类型向json类型的转化对照如下:import json
a = [1,2,3,4]
b ={"k1":1,"k2":2}
c = (1,2,3,4)
json.dumps(a)
'[1, 2, 3, 4]'
json.dumps(b)
'{"k2": 2, "k1": 1}'
json.dumps(c)
'[1, 2, 3, 4]'json.dumps 中的ensure_ascii 参数引起的中文编码问题如果Python Dict字典含有中文,json.dumps 序列化时对中文默认使用的ascii编码import chardet
import json
b = {"name":"中国"}
json.dumps(b)
'{"name": "\\u4e2d\\u56fd"}'
print json.dumps(b)
{"name": "\u4e2d\u56fd"}
chardet.detect(json.dumps(b))
{'confidence': 1.0, 'encoding': 'ascii'}'中国' 中的ascii 字符码,而不是真正的中文。想输出真正的中文需要指定ensure_ascii=Falsejson.dumps(b,ensure_ascii=False)
'{"name": "\xe6\x88\x91"}'
print json.dumps(b,ensure_ascii=False)
{"name": "我"}
chardet.detect(json.dumps(b,ensure_ascii=False))
{'confidence': 0.7525, 'encoding': 'utf-8'}3. json.dump()把Python类型 以 字符串的形式 写到文件中import json
a = [1,2,3,4]
json.dump(a,open("digital.json","w"))
b = {"name":"我"}
json.dump(b,open("name.json","w"),ensure_ascii=False)
json.dump(b,open("name2.json","w"),ensure_ascii=True)4. json.load()读取 文件中json形式的字符串元素 转化成python类型# -*- coding: utf-8 -*-
import json
number = json.load(open("digital.json"))
print number
b = json.load(open("name.json"))
print b['name']实战项目import urllib2
import json
import chardet
url ='http://www.lagou.com/lbs/getAllCitySearchLabels.json?'
request =urllib2.Request(url)
response = urllib2.urlopen(request)
print response.code
resHtml = response.read()
jsonobj = json.loads(resHtml)
print type(jsonobj)
print jsonobj
citylist =[]
allcitys = jsonobj['content']['data']['allCitySearchLabels']
print allcitys.keys()
for key in allcitys:
print type(allcitys[key])
for item in allcitys[key]:
name =item['name'].encode('utf-8')
print name,type(name)
citylist.append(name)
fp = open('city.json','w')
content = json.dumps(citylist,ensure_ascii=False)
print content
fp.write(content)
fp.close()输出:JSONPathJSON 信息抽取类库,从JSON文档中抽取指定信息的工具JSONPath与Xpath区别JsonPath 对于 JSON 来说,相当于 XPATH 对于XML。下载地址:安装方法:下载jsonpath,解压之后执行'python setup.py install'XPathJSONPathResult/store/book/author$.store.book[*].authorthe authors of all books in the store//author$..authorall authors/store/*$.store.*all things in store, which are some books and a red bicycle./store//price$.store..pricethe price of everything in the store.//book[3]$..book[2]the third book//book[last()]$..book[(@.length-1)]$..book[-1:]the last book in order.//book[position()&3]$..book[0,1]$..book[:2]the first two books//book[isbn]$..book[?(@.isbn)]filter all books with isbn number//book[price&10]$..book[?(@.price&10)]filter all books cheapier than 10//*$..*all Elements in XML document. All members of JSON structure.案例import jsonpath
import urllib2
import chardet
url ='http://www.lagou.com/lbs/getAllCitySearchLabels.json'
request =urllib2.Request(url)
response = urllib2.urlopen(request)
print response.code
resHtml = response.read()
##detect charset
print chardet.detect(resHtml)
jsonobj = json.loads(resHtml)
citylist = jsonpath.jsonpath(jsonobj,'$..name')
print citylist
print type(citylist)
fp = open('city.json','w')
content = json.dumps(citylist,ensure_ascii=False)
print content
fp.write(content.encode('utf-8'))
fp.close()XMLxmltodict模块让使用XML感觉跟操作JSON一样Python操作XML的第三方库参考:模块安装:pip install xmltodictimport xmltodict
bookdict = xmltodict.parse("""
&bookstore&
&title lang="eng"&Harry Potter&/title&
&price&29.99&/price&
&title lang="eng"&Learning XML&/title&
&price&39.95&/price&
&/bookstore&
print bookdict.keys()
[u'bookstore']
print json.dumps(bookdict,indent=4)输出结果:
"bookstore": {
"title": {
"@lang": "eng",
"#text": "Harry Potter"
"price": "29.99"
"title": {
"@lang": "eng",
"#text": "Learning XML"
"price": "39.95"
}数据提取总结HTML、XML
正则表达式JSON
转化成Python类型进行操作(json类)XML
转化成Python类型(xmltodict)
正则表达式其他(js、文本、电话号码、邮箱地址)
正则表达式精通网页抓取原理及技术,精通正则表达式,从结构化的和非结构化的数据中获取信息;XPATH、CSS选择器、正则表达式了解各种Web前端技术,包括XHTML/XML/CSS/JavaScript/AJAX等对目标网站进行爬取分析,找到最优化的爬取策略。json.loads的时候出错-&要注意要解码的Json字符的编码1. 如果传入的字符串的编码是基于ASCII的,而不是UTF-8的话,需要指定字符编码参数cencoding对于:dataDict = json.loads(dataJsonStr); 其中dataJsonStr是json字符串,如果其编码本身是非UTF-8的话,比如是GB2312的,那么上述代码,就会导致出错。改为对应的:dataDict = json.loads(dataJsonStr, encoding="GB2312");2. 如果要解析的字符串,本身的编码类型,不是基于ASCII的,那么,调用json.loads之前,需要先将对应字符串,转换为Unicode类型的 还是以上述的:dataDict = json.loads(dataJsonStr, encoding="GB2312");为例,即使你此处的字符串dataJsonStr,已经通过encoding指定了合适的编码,但是由于其中,包含了其他的编码的字符,比如我本身dataJsonStr是GB2312的字符,但是其中又包含了的一些日文字符,此时,json.loads还是会出错,因为此处的dataJsonStr不是以ASCII为基础的字符编码,所以,需要先去将dataJsonStr转换为Unicode,然后再调用json.loads,就可以了。代码如下:dataJsonStrUni = dataJsonStr.decode("GB2312"); dataDict = json.loads(dataJsonStrUni, encoding="GB2312");encode和decode区别decode的作用是将其他编码的字符串转换成unicode编码。如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。encode的作用是将unicode编码转换成其他编码的字符串。如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。爬虫实践篇培养解决问题的思路、编码解码的理解解决问题的思路?如何判断需求数据在哪?
A) 静态数据,可通过查看网页源代码
B) 定位具体哪一个url请求,抓包,在Fidder里面找,怎么快速定位我要的数据呢?(通过Body大小,除了图片之外的Http请求)判断是什么请求方式?Get还是Post
在Composer raw 模拟发送数据
A) 删除Header信息(为什么删除?代码简介美观、易于理解)
B) 如果做翻页,最好拿第二三页做测试,不要用首页(因为有时候第二页是Post请求,而第一是静态Get请求;拿第二页测试的时候返回的是第一页,容易错误还不自知)参考案例Get、Post案例写python程序确认返回数据是什么格式的,返回json还是html
A) 那如果是json呢,格式化数据,应该做存储; B) 那如果是html呢,提取数据,使用XPath、CSS选择器、正则表达式Get和Post1. 右键查看源代码和 F12 Elements区别 右键查看源代码:实质是一个Get请求 F12 Elements是整个页面 所有的请求url 加载完成的页面2. GET 和Post区别的方法 为什么拉钩用的Post,不是表单提交密码,原因是Post用户体验更好;局部加载Urlencodeurlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%提出个问题:中文字符按什么编码格式进行转化成十六进制呢?
utf-8、gb2312、gbk urlencode编码utf-8与utf-8 urlencode区别import urllib
country = u'中国'
country.encode('utf-8')
'\xe4\xb8\xad\xe5\x9b\xbd'
urllib.quote(country.encode('utf-8'))
'%E4%B8%AD%E5%9B%BD'gb2312与gb2312 urlencode区别import urllib
country = u'中国'
country.encode('gb2312')
'\xd6\xd0\xb9\xfa'
urllib.quote(country.encode('gb2312'))
'%D6%D0%B9%FA'案例# -*- coding: utf-8 -*-
import urllib
import chardet
city=u'北京'.encode('utf-8')
district=u'朝阳区'.encode('utf-8')
bizArea=u'望京'.encode('utf-8')
'city':city,
'district':district,
'bizArea':bizArea
print chardet.detect(query['city'])
{'confidence': 0.7525, 'encoding': 'utf-8'}
print urllib.urlencode(query)
city=%E5%8C%97%E4%BA%AC&bizArea=%E6%9C%9B%E4%BA%AC&district=%E6%9C%9B%E4%BA%AC
print 'http://www.lagou.com/jobs/list_Python?px=default&'+urllib.urlencode(query)+'#filterBox'
http://www.lagou.com/jobs/list_Python?px=default&city=%E5%8C%97%E4%BA%AC&bizArea=%E6%9C%9B%E4%BA%AC&district=%E6%9C%9B%E4%BA%AC#filterBox# -*- coding: utf-8 -*-
import urllib
import chardet
keywords=u'手机及配件市场'.encode('gbk')
'keywords':keywords,
print chardet.detect(query['keywords'])
{'confidence': 0.99, 'encoding': 'GB2312'}
print urllib.urlencode(query)
keywords=%CA%D6%BB%FA%BC%B0%C5%E4%BC%FE%CA%D0%B3%A1
print '

我要回帖

更多关于 excel怎么给文件加密 的文章

 

随机推荐