赞
踩
目录导航:
一些表达式进行提取,正则表达式就是其中一种进行数据筛选的表达式。
正则表达式(Regular Expression)
是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
正则表达式通常被用来匹配
、检索
、替换
和分割
那些符合某个模式(规则)的文本。
Python
自1.5版本
起增加了re
模块,它提供Perl风格
的正则表达式模式。
re
模块使 Python
语言拥有全部的正则表达式功能,使用前需要使用 import re
导入此模块
compile
函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
import re
str = 'This year is 2018'
pat = re.compile("[0-9]{4}")
print(pat.findall(str))
#结果:['2018']
re
模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
import re
str = 'This year is 2018'
res = re.findall("[0-9]{4}",str)
print(res)
#结果:['2018']
字符 | 描述 |
---|---|
\cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v] 。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v] 。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
字符 | 描述 |
---|---|
\d | 匹配一个数字字符。等价于[0-9] 。 |
\D | 匹配一个非数字字符。等价于[^0-9] 。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v] 。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v] 。 |
\w | 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]' 。 |
\W | 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]' 。 |
字符 | 描述 |
---|---|
. | 匹配除 “\n” 之外的任何单个字符。 要匹配包括 ‘\n’ 在内的任何字符,请使用像"(.¦\n)"的模式。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 “plain” 中的’p’、‘l’、‘i’、‘n’。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。 例如,’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。 例如,'[^a-z]' 可以匹配任何不在 ‘a’ 到 'z’范围内的任意字符。 |
* | 匹配前面的子表达式零次或多次。例如,zo 能匹配 “z” 以及 “zoo”。 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。 例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 或 “does” 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。 例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,‘n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘’ 匹配 “” 而 “(” 则匹配 “(”。 |
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 |
? | 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。 |
(pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘(’ 或 ‘)’。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (¦) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y¦ies) 就是一个比’industry¦industries’更简略的表达式。 |
x¦y | 匹配 x 或 y。例如,‘z¦food’ 能匹配 “z” 或 “food”。’(z¦f)ood’ 则匹配 “zood” 或 “food”。 |
import re
rst = re.rearch('',str)
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
string = "Python"
pat = "pyt"
rst = re.search(pat,string,re.I) # 第三个参数
print(rst)
.*? 的使用
re
模块来实现正则匹配。编译正则表达式模式,返回一个正则对象
的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)
格式:
re.compile(pattern[,flags=0])
pattern
: 编译时用的表达式字符串。flags
: 编译标志位,用于修改正则表达式的匹配方式,如:re.I(不区分大小写)、re.S等import re
tt = "Tina is a good girl, she is cool, clever, and so on..."
rr = re.compile(r'\w*oo\w*')
print(rr.findall(tt)) #查找所有包含'oo'的单词
# 执行结果如下:
# ['good', 'cool']
re.match(pattern, string[, flags=0])
print(re.match('com','comwww.csdn').group())
print(re.match('com','Comwww.csdn',re.I).group())
#执行结果如下:
#com
#com
re.search(pattern, string[, flags=0])
print(re.search('\dcom','www.4comcsdn.5com').group())
执行结果如下:
# 4com
import re
a = "123abc456"
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)) #123abc456,返回整体
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)) #123
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)) #abc
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)) #456
###group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。###
re.findall(pattern, string[, flags=0])
p = re.compile(r'\d+')
print(p.findall('o1n2m3k4'))
执行结果如下:
['1', '2', '3', '4']
import re
tt = "Tina is a good girl, she is cool, clever, and so on..."
rr = re.compile(r'\w*oo\w*')
print(rr.findall(tt))
print(re.findall(r'(\w)*oo(\w)',tt))#()表示子表达式
执行结果如下:
['good', 'cool']
[('g', 'd'), ('c', 'l')]
re.finditer(pattern, string[, flags=0])
iter = re.finditer(r'\d+','12 drumm44ers drumming, 11 ... 10 ...') for i in iter: print(i) print(i.group()) print(i.span()) ''' # 执行结果如下: <_sre.SRE_Match object; span=(0, 2), match='12'> 12 (0, 2) <_sre.SRE_Match object; span=(8, 10), match='44'> 44 (8, 10) <_sre.SRE_Match object; span=(24, 26), match='11'> 11 (24, 26) <_sre.SRE_Match object; span=(31, 33), match='10'> 10 (31, 33) '''
按照能够匹配的子串将string分割后返回列表。
可以使用re.split来分割字符串,如:re.split(r’\s+’, text);将字符串按空格分割成一个单词列表。
格式:
re.split(pattern, string[, maxsplit])
maxsplit
: 用于指定最大分割次数,不指定将全部分割。print(re.split('\d+','one1two2three3four4five5'))
# 执行结果如下:
# ['one', 'two', 'three', 'four', 'five', '']
re.sub(pattern, repl, string, count)
import re
text = "JGood is a handsome boy, he is cool, clever, and so on..."
print(re.sub(r'\s+', '-', text))
执行结果如下:
JGood-is-a-handsome-boy,-he-is-cool,-clever,-and-so-on...
其中第二个函数是替换后的字符串;本例中为'-'
第四个参数指替换个数。默认为0,表示每个匹配项都替换。
import re
text = "JGood is a handsome boy, he is cool, clever, and so on..."
print(re.sub(r'\s+', lambda m:'['+m.group(0)+']', text,0))
执行结果如下:
JGood[ ]is[ ]a[ ]handsome[ ]boy,[ ]he[ ]is[ ]cool,[ ]clever,[ ]and[ ]so[ ]on...
subn(pattern, repl, string, count=0, flags=0)
print(re.subn('[1-2]','A','123456abcdef'))
print(re.sub("g.t","have",'I get A, I got B ,I gut C'))
print(re.subn("g.t","have",'I get A, I got B ,I gut C'))
执行结果如下:
('AA3456abcdef', 2)
I have A, I have B ,I have C
('I have A, I have B ,I have C', 3)
a=re.search('[\d]',"abc33").group()
print(a)
p=re.match('[\d]',"abc33")
print(p)
b=re.findall('[\d]',"abc33")
print(b)
执行结果:
3
None
['3', '3']
<!DOCTYPE html> <html> <head> <title>Python 正则表达式实例</title> </head> <body> <h2>常用网站链接</h2> <ul> <li><a href="https://www.python.org">Python官方网站</a></li> <li><a href="https://www.djangoproject.com">Django官方网站</a></li> <li><a href="https://www.baidu.com">百度搜索引擎</a></li> <li><a href="https://blog.csdn.net">CSDN官方网站</a></li> <li><a href="https://edu.csdn.net/">CSDN学院</a></li> </ul> </body> </html>
import re f = open("./index.html","r") content = f.read() f.close() #print(content) title = re.search("<title>(.*?)</title>",content) if title: print(title) print("标题:"+title.group()) alist = re.findall('<a href="(.*?)">(.*?)</a>',content) for ov in alist: print(ov[1]+":"+ov[0]) `
]
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>JavaScript--实例</title> </head> <body> <h3 id="hid">JavaScript实例--表单事件</h3> <form action="my.html" name="myform" method="post" onsubmit="return doSubmit()"> 账号:<input type="text" name="uname"/> 8-16位的有效字符<br/><br/> 密码:<input type="password" name="upass"/> 6-18位<br/><br/> 邮箱:<input type="text" name="email"/> <br/><br/> <input type="submit" value="提交"/> </form> <script type="text/javascript"> //表单提交事件处理 function doSubmit(){ //验证账号 var name = document.myform.uname.value; if(name.match(/^\w{8,16}$/)==null){ alert("账号必须为8-16的有效字符!"); return false; } //验证密码 var pass = document.myform.upass.value; if(pass.match(/^.{6,18}$/)==null){ alert("密码必须为6-18位!"); return false; } //验证邮箱 var email = document.myform.email.value; if(email.match(/^\w+@\w+(\.\w+){1,2}$/)==null){ alert("请输入正确的Email地址!"); return false; } return true; } </script> </body> </html>
MariaDB [mydb]> select * from stu; +----+----------+-----+-----+----------+ | id | name | age | sex | classid | +----+----------+-----+-----+----------+ | 1 | zhangsan | 22 | m | python03 | | 2 | lisi | 25 | w | python04 | | 3 | wangwu | 20 | m | python03 | | 4 | zhaoliu | 19 | w | python04 | | 5 | qq01 | 20 | m | python03 | | 6 | qqmn | 21 | w | python04 | | 7 | qq03 | 20 | m | python05 | | 8 | uu01 | 21 | w | python04 | | 9 | uu02 | 20 | m | python05 | | 10 | aa | 29 | w | python03 | | 11 | bb | 20 | m | python04 | | 16 | abc | 25 | m | python05 | +----+----------+-----+-----+----------+ 12 rows in set (0.00 sec) -- 使用正则查询姓名是使用任意两位小写字母构成的数据信息 MariaDB [mydb]> select * from stu where name regexp '^[a-z]{2}$'; +----+------+-----+-----+----------+ | id | name | age | sex | classid | +----+------+-----+-----+----------+ | 10 | aa | 29 | w | python03 | | 11 | bb | 20 | m | python04 | +----+------+-----+-----+----------+ 2 rows in set (0.00 sec) --查询name的值为2~4位的小写字母 MariaDB [mydb]> select * from stu where name regexp '^[a-z]{2,4}$'; +----+------+-----+-----+----------+ | id | name | age | sex | classid | +----+------+-----+-----+----------+ | 2 | lisi | 25 | w | python04 | | 6 | qqmn | 21 | w | python04 | | 10 | aa | 29 | w | python03 | | 11 | bb | 20 | m | python04 | | 16 | abc | 25 | m | python05 | +----+------+-----+-----+----------+ 5 rows in set (0.00 sec) -- 查询name字段值是由两位字母加两位数字构成的数据信息 MariaDB [mydb]> select * from stu where name regexp '^[a-z]{2}[0-9]{2}$'; +----+------+-----+-----+----------+ | id | name | age | sex | classid | +----+------+-----+-----+----------+ | 5 | qq01 | 20 | m | python03 | | 7 | qq03 | 20 | m | python05 | | 8 | uu01 | 21 | w | python04 | | 9 | uu02 | 20 | m | python05 | +----+------+-----+-----+----------+ 4 rows in set (0.00 sec) MariaDB [mydb]>
科学研究
、Web安全
、产品研发
、舆情监控
等领域可以做很多事情。几乎每个网站都有一个名为robots.txt的文档,当然也有有些网站没有设定。对于没有设定robots.txt的网站可以通过网络爬虫获取没有口令加密的数据,也就是该网站所有页面的数据都可以爬取。如果网站有文件robots.txt文档,就要判断是否有禁止访客获取数据 如:https://www.taobao.com/robots.txt
在Python2版本中,有urllib和urlib2两个库可以用来实现request的发送。
而在Python3中,已经不存在urllib2这个库了,统一为urllib。
Python3 urllib库官方链接:
https://docs.python.org/3/library/urllib.html
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None,
unverifiable=False, method=None)
案例:爬取百度新闻首页的新闻标题信息
url地址:http://news.baidu.com/
具体实现步骤:
具体代码如下:
import urllib.request import re url = "http://news.baidu.com/" #伪装浏览器用户 headers = {'User-Agent':'User-Agent:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)'} req = urllib.request.Request(url,headers=headers) #执行请求获取响应信息 res = urllib.request.urlopen(req) # 从响应对象中读取信息并解码 html = res.read().decode("utf-8") #print(len(html)) #使用正则解析出新闻标题信息 pat = '<a href="(.*?)" .*? target="_blank">(.*?)</a>' dlist = re.findall(pat,html) # 遍历输出结果 for v in dlist: print(v[1]+":"+v[0])
urllib.error
可以接收有urllib.request
产生的异常。urllib.error
有两个类,URLError
和HTTPError
。URLError
内有一个属性:reason
返回错误的原因# 测试URLError的异常处理
from urllib import request
from urllib import error
url = "http://www.wer3214e13wer3.com/"
req = request.Request(url)
try:
response = request.urlopen(req)
html = response.read().decode('utf-8')
print(len(html))
except error.URLError as e:
print(e.reason) #输出错误信息
print("ok")
[Errno 8] nodename nor servname provided, or not known
ok
HTTPError
内有三个属性:code
返回HTTP状态码,如404 ; reason
返回错误原因; headers
返回请求头# 测试HTTPError的异常处理
from urllib import request
from urllib import error
url = "https://img-ads.csdn.net/2018/20180420184005werqwefsd9410.png"
req = request.Request(url)
try:
response = request.urlopen(req)
html = response.read().decode('utf-8')
print(len(html))
except error.HTTPError as e:
print(e.reason) #输出错误信息
print(e.code) #输出HTTP状态码
print("ok")
Not Found
404
ok
URLError
是OSError
的一个子类,HTTPError
是URLError
的一个子类:from urllib import request from urllib import error #url = "https://img-ads.csdn.net/2018/20180420184005werqwefsd9410.png" url = "http://www.wer3214e13wer3.com/" req = request.Request(url) try: response = request.urlopen(req) html = response.read().decode('utf-8') print(len(html)) except error.HTTPError as e: print("HTTPError") print(e.reason) print(e.code) except error.URLError as e: print("URLError") print(e.reason) # 输出错误信息 print("ok")
from urllib import request from urllib import error url = "https://img-ads.csdn.net/2018/20180420184005werqwefsd9410.png" #url = "http://www.wer3214e13wer3.com/" req = request.Request(url) try: response = request.urlopen(req) html = response.read().decode('utf-8') print(len(html)) except Exception as e: if hasattr(e,'reason'): print(e.reason) if hasattr(e,'code'): print(e.code) print("ok") Not Found 404 ok zhang
urllib3
和 requests
, 本节会分别介绍一下,以后我们着重使用requests
。 pip install urllib3
import urllib3 import re # 实例化产生请求对象 http = urllib3.PoolManager() # get请求指定网址 url = "http://www.baidu.com" res = http.request("GET",url) # 获取HTTP状态码 print("status:%d" % res.status) # 获取响应内容 data = res.data.decode("utf-8") # 正则解析并输出 print(re.findall("<title>(.*?)</title>",data))
import urllib3 import re url = "http://www.baidu.com" http = urllib3.PoolManager(timeout = 4.0) #设置超时时间 res = http.request( "GET", url, #headers={ # 'User-Agent':'Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1', #}, fields={'id':100,'name':'lisi'}, #请求参数信息 ) print("status:%d" % res.status) data = res.data.decode("utf-8") print(re.findall("<title>(.*?)</title>",data))
pip install requests
import requests import re url = "http://www.baidu.com" # 抓取信息 res = requests.get(url) #获取HTTP状态码 print("status:%d" % res.status_code) # 获取响应内容 data = res.content.decode("utf-8") #解析出结果 print(re.findall("<title>(.*?)</title>",data))
from urllib import request from urllib import error import re url = "http://bj.58.com/job/?key=python&final=1&jump=1" req = request.Request(url) try: response = request.urlopen(req) html = response.read().decode('utf-8') pat = '<span class="address" >(.*?)</span> \| <span class="name">(.*?)</span>' dlist = re.findall(pat,html) #print(len(dlist)) for v in dlist: print(v[0]+" | "+v[1]) except error.URLError as e: print(e.reason) #输出错误信息 print("ok")
import requests import re data = { 'key':'python', 'final':1, 'jump':1, } url = "http://bj.58.com/job/" res = requests.get(url,params=data) html = res.content.decode('utf-8') pat = '<span class="address" >(.*?)</span> \| <span class="name">(.*?)</span>' dlist = re.findall(pat,html) print(len(dlist)) for v in dlist: print(v[0]+" | "+v[1])
import json
json.loads(json_str) # json字符串转换成字典
json.dumps(dict) # 字典转换成json字符串
from urllib import request,parse import json url = 'http://fanyi.baidu.com/sug' # 定义请求参数 data = { 'kw' : 'python' } data = parse.urlencode(data) #编码转换 # 封装headers头信息 headers = { 'Content-Length' : len(data) } # 发送请求,抓取信息 req = request.Request(url=url,data=bytes(data,encoding='utf-8'),headers=headers) res = request.urlopen(req) # 解析结果并输出 str_json = res.read().decode('utf-8') # json myjson = json.loads(str_json) # 把json转字典 info = myjson['data'][0]['v'] print(info)
import requests import json url = 'http://fanyi.baidu.com/sug' # 定义请求参数 data = { 'kw' : 'python' } # 发送请求,抓取信息 res = requests.post(url,data=data) # 解析结果并输出 str_json = res.content.decode('utf-8') # 获取响应的json字串 myjson = json.loads(str_json) # 把json转字典 info = myjson['data'][0]['v'] print(info)
import requests import json def fanyi(keyword): url = 'http://fanyi.baidu.com/sug' # 定义请求参数 data = { 'kw' : keyword } # 发送请求,抓取信息 res = requests.post(url,data=data) # 解析结果并输出 str_json = res.content.decode('utf-8') # 获取响应的json字串 myjson = json.loads(str_json) # 把json转字典 info = myjson['data'][0]['v'] print(info) if __name__ == '__main__': while True: keyword = input('输入翻译的单词:') if keyword == 'q': break fanyi(keyword)
from urllib import request,parse import json def fanyi(keyword): base_url = 'http://fanyi.baidu.com/sug' # 构建请求对象 data = { 'kw' : keyword } data = parse.urlencode(data) headers = { 'Content-Length':len(data) } req = request.Request(url=base_url,data=bytes(data,encoding='utf-8'),headers=headers) res = request.urlopen(req) str_json = res.read().decode('utf-8') # 获取响应的json字串 myjson = json.loads(str_json) # 把json转字典 info = myjson['data'][0]['v'] print(info) if __name__ == '__main__': while True: keyword = input('输入翻译的单词:') if keyword == 'q': break fanyi(keyword)
from urllib import request,parse login_url = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2018321648829' data = { 'email':'1352*****6', 'icode':'', 'origURL':'http://www.renren.com/home', 'domain':'renren.com', 'key_id':'1', 'captcha_type':'web_login', 'password':'478b7c2dca554eeabed3b7374703bff4a6a22e78b8a9fcfb090e3a7fb792992b', 'rkey':'e954ec64a7ecf4e33bdf81bb1abad158', 'f':'http%3A%2F%2Fwww.renren.com%2F965541786', } data = parse.urlencode(data) headers = { 'Content-Length' : len(data) } req = request.Request(url=login_url,data=bytes(data,encoding='utf-8'),headers=headers,) response = request.urlopen(req) print(response.read().decode('utf-8'))
from urllib import request import re,gzip base_url = 'http://www.renren.com/965541786' headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'Cookie': 'anonymid=jgdcqcjgqy4yxt; depovince=BJ; _r01_=1; JSESSIONID=abc7HUv9M_HsB7WkgK2lw; ick_login=b954cf62-bbe5-480d-b679-e1e3ce584896; SL_GWPT_Show_Hide_tmp=1; SL_wptGlobTipTmp=1; ick=b4337770-b7ce-4a70-b9d0-cd63c7fc7bb5; XNESSESSIONID=738f4bde312f; jebe_key=f950add1-40e8-4009-a157-bfc3d89f7350%7C24a48cb369f8637c5ee2c4a23eb5b93f%7C1524555370510%7C1%7C1524555375485; first_login_flag=1; ln_uact=13520319616; ln_hurl=http://head.xiaonei.com/photos/0/0/men_main.gif; wp_fold=0; jebecookies=ef7f7372-0e70-45db-aaae-c415d4611918|||||; _de=8C2F648D7158ED727318288C8F3F21C5; p=f1ea4b6984cefb7d88164a67816c91fe6; t=401516286d37bde6735180d25f68f2fe6; societyguester=401516286d37bde6735180d25f68f2fe6; id=965541786; xnsid=928c27b; ver=7.0; loginfrom=null', 'Host': 'www.renren.com', 'Referer': 'http://www.renren.com/SysHome.do', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36', } req = request.Request(url=base_url,headers=headers) res = request.urlopen(req) #html = res.read().decode("utf-8") # 网页响应时开启了gzip压缩,需要解压 #报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte # 获取将请求头中的Accept-Encoding的gzip删除也可以 # 对gzip压缩的响应,我们解压后转码 html = gzip.decompress(res.read()).decode("utf-8") #print(html) print(re.findall("<title>(.*?)</title>",html))
from urllib import request,parse import re,gzip,time # cookie管理模块, from http import cookiejar # 返回存储cookie对象 cookie = cookiejar.CookieJar() # 返回一个cookie管理器 cookie_handler = request.HTTPCookieProcessor(cookie) # 请求管理器 opener = request.build_opener(cookie_handler) def doLogin(): login_url = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2018321648829' data = { 'email':'1352*****16', 'icode':'', 'origURL':'http://www.renren.com/home', 'domain':'renren.com', 'key_id':'1', 'captcha_type':'web_login', 'password':'478b7c2dca554eeabed3b7374703bff4a6a22e78b8a9fcfb090e3a7fb792992b', 'rkey':'e954ec64a7ecf4e33bdf81bb1abad158', 'f':'http%3A%2F%2Fwww.renren.com%2F965541786', } data = parse.urlencode(data) headers = { 'Content-Length' : len(data) } req = request.Request(url=login_url,data=bytes(data,encoding='utf-8'),headers=headers,) response = opener.open(req) def myHome(): home_url = 'http://www.renren.com/965541786' res = opener.open(home_url) html = res.read().decode("utf-8") #print(html) print(re.findall("<title>(.*?)</title>",html)) if __name__ == '__main__': # 登陆 print("正在登录中...") doLogin() time.sleep(3) # 访问个人首页 myHome()
import requests import re,time s = requests.Session() def doLogin(): login_url = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2018321648829' data = { 'email':'1352*****6', 'icode':'', 'origURL':'http://www.renren.com/home', 'domain':'renren.com', 'key_id':'1', 'captcha_type':'web_login', 'password':'478b7c2dca554eeabed3b7374703bff4a6a22e78b8a9fcfb090e3a7fb792992b', 'rkey':'e954ec64a7ecf4e33bdf81bb1abad158', 'f':'http%3A%2F%2Fwww.renren.com%2F965541786', } s.post(login_url,data=data) def myHome(): home_url = 'http://www.renren.com/965541786' res = s.get(home_url) html = res.content.decode("utf-8") #print(html) print(re.findall("<title>(.*?)</title>",html)) if __name__ == '__main__': # 登陆 print("正在登录中...") doLogin() time.sleep(3) # 访问个人首页 myHome()
from urllib import request,error import re,time,json def getPage(url): '''爬取指定url页面信息''' try: #定义请求头信息 headers = { 'User-Agent':'User-Agent:Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1' } # 封装请求对象 req = request.Request(url,headers=headers) # 执行爬取 res = request.urlopen(req) #判断响应状态,并响应爬取内容 if res.code == 200: return res.read().decode("utf-8") else: return None except error.URLError: return None def parsePage(html): '''解析爬取网页中的内容,并返回字段结果''' #定义解析正则表达式 pat = '<i class="board-index board-index-[0-9]+">([0-9]+)</i>.*?<img data-src="(.*?)" alt="(.*?)" class="board-img" />.*?<p class="star">(.*?)</p>.*?<p class="releasetime">(.*?)</p>.*?<i class="integer">([0-9\.]+)</i><i class="fraction">([0-9]+)</i>' #执行解析 items = re.findall(pat,html,re.S) #遍历封装数据并返回 for item in items: yield { 'index':item[0], 'image':item[1], 'title':item[2], 'actor':item[3].strip()[3:], 'time':item[4].strip()[5:], 'score':item[5]+item[6], } def writeFile(content): '''执行文件追加写操作''' #print(content) with open("./result.txt",'a',encoding='utf-8') as f: f.write(json.dumps(content,ensure_ascii=False) + "\n") #json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False def main(offset): ''' 主程序函数,负责调度执行爬虫处理 ''' url = 'http://maoyan.com/board/4?offset=' + str(offset) #print(url) html = getPage(url) #判断是否爬取到数据,并调用解析函数 if html: for item in parsePage(html): writeFile(item) # 判断当前执行是否为主程序运行,并遍历调用主函数爬取数据 if __name__ == '__main__': for i in range(10): main(offset=i*10) time.sleep(1)
from requests.exceptions import RequestException import requests import re,time,json def getPage(url): '''爬取指定url页面信息''' try: #定义请求头信息 headers = { 'User-Agent':'User-Agent:Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1' } # 执行爬取 res = requests.get(url,headers=headers) #判断响应状态,并响应爬取内容 if res.status_code == 200: return res.text else: return None except RequestException: return None def parsePage(html): '''解析爬取网页中的内容,并返回字段结果''' #定义解析正则表达式 pat = '<i class="board-index board-index-[0-9]+">([0-9]+)</i>.*?<img data-src="(.*?)" alt="(.*?)" class="board-img" />.*?<p class="star">(.*?)</p>.*?<p class="releasetime">(.*?)</p>.*?<i class="integer">([0-9\.]+)</i><i class="fraction">([0-9]+)</i>' #执行解析 items = re.findall(pat,html,re.S) #遍历封装数据并返回 for item in items: yield { 'index':item[0], 'image':item[1], 'title':item[2], 'actor':item[3].strip()[3:], 'time':item[4].strip()[5:], 'score':item[5]+item[6], } def writeFile(content): '''执行文件追加写操作''' #print(content) with open("./result.txt",'a',encoding='utf-8') as f: f.write(json.dumps(content,ensure_ascii=False) + "\n") #json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False def main(offset): ''' 主程序函数,负责调度执行爬虫处理 ''' url = 'http://maoyan.com/board/4?offset=' + str(offset) #print(url) html = getPage(url) #判断是否爬取到数据,并调用解析函数 if html: for item in parsePage(html): writeFile(item) # 判断当前执行是否为主程序运行,并遍历调用主函数爬取数据 if __name__ == '__main__': for i in range(10): main(offset=i*10) time.sleep(1)
W3C XSLT
标准的主要元素,并且 XQuery
和 XPointer
都构建于 XPath 表达之上。http://lxml.de
官方文档:http://lxml.de/api/index.html
pip install lxml
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从当前节点选取直接子节点 |
// | 从匹配选择的当前节点选择所有子孙节点,而不考虑它们的位置 |
. | 选取当前节点。 |
… | 选取当前节点的父节点。 |
@ | 选取属性。 |
运算符 | 描述 | 实例 | 返回值 |
---|---|---|---|
¦ | 计算两个节点集 | //book ¦ //cd | 返回所有拥有 book 和 cd 元素的节点集 |
+ | 加法 | 6 + 4 | 10 |
- | 减法 | 6 - 4 | 2 |
* | 乘法 | 6 * 4 | 24 |
div | 除法 | 8 div 4 | 2 |
= | 等于 | price=9.80 | 如果 price 是 9.80,则返回 true。、\n 如果 price 是 9.90,则返回 false。 |
!= | 不等于 | price!=9.80 | 如果 price 是 9.90,则返回 true。\n 如果 price 是 9.80,则返回 false。 |
< | 小于 | price<9.80 | 如果 price 是 9.00,则返回 true。\n 如果 price 是 9.90,则返回 false。 |
<= | 小于或等于 | price<=9.80 | 如果 price 是 9.00,则返回 true。\n 如果 price 是 9.90,则返回 false。 |
> | 大于 | price>9.80 | 如果 price 是 9.90,则返回 true。\n如果 price 是 9.80,则返回 false。 |
>= | 大于或等于 | price>=9.80 | 如果 price 是 9.90,则返回 true。\n如果 price 是 9.70,则返回 false。 |
or | 或 | price=9.80 or price=9.70 | 如果 price 是 9.80,则返回 true。\n如果 price 是 9.50,则返回 false。 |
and | 与 | price>9.00 and price<9.90 | 如果 price 是 9.80,则返回 true。\n如果 price 是 8.50,则返回 false。 |
mod | 计算除法的余数 | 5 mod 2 | 1 |
<!DOCTYPE html> <html> <head> <title>我的网页</title> </head> <body> <h3 id="hid">我的常用链接</h3> <ul> <li class="item-0"><a href="http://www.baidu.com">百度</a></li> <li class="item-1 shop"><a href="http://www.jd.com">京东</a></li> <li class="item-2"><a href="http://www.sohu.com">搜狐</a></li> <li class="item-3"><a href="http://www.sina.com">新浪</a></li> <li class="item-4 shop"><a href="http://www.taobao.com">淘宝</a></li> </ul> </body> </html>
# 导入模块 from lxml import etree # 读取html文件信息(在真实代码中是爬取的网页信息) f = open("./my.html",'r',encoding="utf-8") content = f.read() f.close() # 解析HTML文档,返回根节点对象 html = etree.HTML(content) #print(html) # <Element html at 0x103534c88> # 获取网页中所有标签并遍历输出标签名 result = html.xpath("//*") for t in result: print(t.tag,end=" ") #[html head title body h3 ul li a li a ... ... td] print() # 获取节点 result = html.xpath("//li") # 获取所有li节点 result = html.xpath("//li/a") # 获取所有li节点下的所有直接a子节点 result = html.xpath("//ul//a") # 效果同上(ul下所有子孙节点) result = html.xpath("//a/..") #获取所有a节点的父节点 print(result) # 获取属性和文本内容 result = html.xpath("//li/a/@href") #获取所有li下所有直接子a节点的href属性值 result = html.xpath("//li/a/text()") #获取所有li下所有直接子a节点内的文本内容 print(result) #['百度', '京东', '搜狐', '新浪', '淘宝'] result = html.xpath("//li/a[@class]/text()") #获取所有li下所有直接含有class属性子a节点内的文本内容 print(result) #['百度', '搜狐', '新浪'] #获取所有li下所有直接含有class属性值为aa的子a节点内的文本内容 result = html.xpath("//li/a[@class='aa']/text()") print(result) #['搜狐', '新浪'] #获取class属性值中含有shop的li节点下所有直接a子节点内的文本内容 result = html.xpath("//li[contains(@class,'shop')]/a/text()") print(result) #['搜狐', '新浪'] # 按序选择 result = html.xpath("//li[1]/a/text()") # 获取每组li中的第一个li节点里面的a的文本 result = html.xpath("//li[last()]/a/text()") # 获取每组li中最后一个li节点里面的a的文本 result = html.xpath("//li[position()<3]/a/text()") # 获取每组li中前两个li节点里面的a的文本 result = html.xpath("//li[last()-2]/a/text()") # 获取每组li中倒数第三个li节点里面的a的文本 print(result) print("--"*30) # 节点轴选择 result = html.xpath("//li[1]/ancestor::*") # 获取li的所有祖先节点 result = html.xpath("//li[1]/ancestor::ul") # 获取li的所有祖先中的ul节点 result = html.xpath("//li[1]/a/attribute::*") # 获取li中a节点的所有属性值 result = html.xpath("//li/child::a[@href='http://www.sohu.com']") #获取li子节点中属性href值的a节点 result = html.xpath("//body/descendant::a") # 获取body中的所有子孙节点a print(result) result = html.xpath("//li[3]") #获取li中的第三个节点 result = html.xpath("//li[3]/following::li") #获取第三个li节点之后所有li节点 result = html.xpath("//li[3]/following-sibling::*") #获取第三个li节点之后所有同级li节点 for v in result: print(v.find("a").text)
# 导入模块 from lxml import etree # 读取html文件信息(在真实代码中是爬取的网页信息) f = open("./my.html",'r') content = f.read() f.close() # 解析HTML文档,返回根节点对象 html = etree.HTML(content) # 1. 获取id属性为hid的h3节点中的文本内容 print(html.xpath("//h3[@id='hid']/text()")) #['我的常用链接'] # 2. 获取li中所有超级链接a的信息 result = html.xpath("//li/a") for t in result: # 通过xapth()二次解析结果 #print(t.xpath("text()")[0], ':', t.xpath("@href")[0]) # 效果同上,使用节点对象属性方法解析 print(t.text, ':', t.get("href")) ''' #结果: 百度 : http://www.baidu.com 京东 : http://www.jd.com 搜狐 : http://www.sohu.com 新浪 : http://www.sina.com 淘宝 : http://www.taobao.com ''' ''' HTML元素的属性: tag:元素标签名 text:标签中间的文本 HTML元素的方法: find() 查找一个匹配的元素 findall() 查找所有匹配的元素 get(key, default=None) 获取指定属性值 items()获取元素属性,作为序列返回 keys()获取属性名称列表 value是()将元素属性值作为字符串序列 '''
pip install lxml
pip install beautifulsoup4
官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/
中文文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
PyPI: https://pypi.python.org/pypi/beautifulsoup4
主要的解析器,以及它们的优缺点:
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
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语言库 |
html5lib | BeautifulSoup(markup, “html5lib”) | 最好的容错性,以浏览器的方式解析文档,生成HTML5格式的文档 | 速度慢、不依赖外部扩展 |
# 导入模块 from bs4 import BeautifulSoup # 读取html文件信息(在真实代码中是爬取的网页信息) f = open("./my.html",'r',encoding="utf-8") content = f.read() f.close() # 创建解析器 soup = BeautifulSoup(content,"lxml") # 输出网页内容:注:此内容已被缩进格式化(自动更正格式),其实这个是在上一步实例化时就已完成 print(soup.prettify()) #输出网页中title标签中的内容 print(soup.title.string)
...
print(soup.title) #<title>我的网页</title>
print(type(soup.title)) #<class 'bs4.element.Tag'>
print(soup.head) #获取整个head元素,及内部元素
print(soup.li) #获取第一个li元素(后面其他li不会获取)
# <li class="item-0"><a class="bb" href="http://www.baidu.com">百度</a></li>
...
print(soup.a) #获取第一个a元素标签: <a class="bb" href="http://www.baidu.com">百度</a>
print(soup.a.name) #获取标签名: a
print(soup.a.attrs) #获取所有属性:{'class': ['bb'], 'href': 'http://www.baidu.com'}
print(soup.a.attrs['href']) #获取其中一个属性:http://www.baidu.com
print(soup.a.string) # 获取元素标签中间的文本内容:百度
print(soup.li.a) #获取网页中第一个li中的第一个a元素节点
#输出 <a class="bb" href="http://www.baidu.com">百度</a>
print(type(soup.body.h3)) ##获取body中的第一个h3元素的类型:<class 'bs4.element.Tag'>
print(soup.body.h3.string) #获取body中的第一个h3中的文本内容: 我的常用链接
#.... # 子或子孙节点 # 以下获取的节点列表都可以使用for...in遍历 print(soup.ul.contents) #获取ul下面的所有直接子节点,返回列表 print(soup.ul.children) #获取ul下面的所有直接子节点,返回一个:<list_iterator object at 0x110346a20> print(soup.ul.descendants) # 获取ul下的所有子孙节点。 for v in soup.ul.descendants: print("a:",v) # 父祖节点 print(soup.a.parent.name) #通过parent属性获取a的父节点 li # print(list(soup.a.parents)) # 获取所有祖先节点 #兄弟节点 print(soup.li.next_siblings) #获取指定li节点的所有后面的兄弟节点 print(soup.li.previous_siblings)#获取指定li节点的所有前面的兄弟节点 #for v in soup.li.next_siblings: # print(v) # 获取信息 print(soup.a.string) #获取a节点中的文本 print(soup.a.attrs['href']) # 或a节点的href属性值
find_all(name,attrs,recursive,text, **kwargs )
# 导入模块 from bs4 import BeautifulSoup import re # 读取html文件信息(在真实代码中是爬取的网页信息) f = open("./my.html",'r') content = f.read() f.close() # 创建解析器 soup = BeautifulSoup(content,"lxml") # 通过name指定li值,获取所有li元素节点,返回列表 lilist = soup.find_all(name="li") # 通过attrs指定属性来获取所有元素节点 lilist = soup.find_all(attrs={"class":"aa"}) lilist = soup.find_all(class_="aa") #同上(class属性中包含就可以了) lilist = soup.find_all(class_="shop") #class属性值中包含shop的所有节点 lilist = soup.find_all(id="hid") #<h3 id="hid">我的常用链接</h3> # 通过文本内容获取 lilist = soup.find_all(text='百度') # 百度 lilist = soup.find_all(text=re.compile('张')) # 张翠山 张无忌 for i in lilist: print(i)
# 获取一个li元素节点
lilist = soup.find(name="li")
# 通过attrs指定属性来获取一个元素节点
lilist = soup.find(attrs={"class":"aa"})
# 导入模块 from bs4 import BeautifulSoup import re # 读取html文件信息(在真实代码中是爬取的网页信息) f = open("./my.html",'r') content = f.read() f.close() # 创建解析器 soup = BeautifulSoup(content,"lxml") print(soup.select("ul li a")) #获取ul里面li下面的a元素节点 print(soup.select("#hid")) #获取id属性值为hid的元素节点 print(soup.select("li.shop a")) #获取class属性为shop的li元素里面所有的a元素节点 # 套用选择解析器 blist = soup.select("ul li") for li in blist: a = li.select("a")[0] #获取每个li里面的a元素节点 print(a) print(a['href']) #获取属性href的值 # print(a.attrs['href']) #等价 同上 获取属性值 print(a.get_text()) #等价 print(a.string) 获取元素节点的文本内容
PyQuery库也是一个非常强大又灵活的网页解析库,如果你有前端开发经验的,都应该接触过jQuery,那么PyQuery就是你非常绝佳的选择。
PyQuery 是 Python 仿照 jQuery 的严格实现。
语法与 jQuery 几乎完全相同,所以不用再去费心去记一些奇怪的方法了。
官网地址:http://pyquery.readthedocs.io/en/latest/
jQuery参考文档: http://jquery.cuishifeng.cn/
PyQuery的安装
pip install pyquery
# URL初始化 from pyquery import PyQuery as pq doc = pq(url="http://www.baidu.com",encoding="utf-8") print(doc('title')) # 文件初始化 from pyquery import PyQuery as pq doc = pq(filename='my.html',encoding="utf-8") print(doc('title')) ''' # 推荐使用requests爬取信息 from pyquery import PyQuery as pq import requests res = requests.get("http://www.baidu.com") res.encoding = "utf-8" #因为原编码为ISO-8859-1 #print(res.text) doc = pq(res.text) print(doc("title"))
# 读取my.html的文件内容,并使用pyquery来查找节点 from pyquery import PyQuery as pq doc = pq(filename='my.html',encoding="utf-8") print(doc('title')) #通过html标签名获取元素节点 print(doc('#hid')) #获取id属性值为hid的元素节点 print(doc('.bb')) #获取class属性值为bb的元素节点 print(doc('title,h3')) #选择符组的使用 print(doc("ul li.shop a")) #关联选择符的使用 print(doc("a")) #获取所有a print(doc("a:first")) #获取第一个a print(doc("a:last")) #获取最后一个a print(doc("a:lt(2)")) #获取前连个a print(doc("a:eq(2)")) #获取索引位置2的a(第三个) print(doc('a[href="http://www.sina.com"]')) #获取指定属性值的节点 print("="*60) # 节点的二次筛选: lilist = doc("ul li") #获取ul中所有的li print(type(lilist)) #<class 'pyquery.pyquery.PyQuery'> print(lilist.find("a.bb")) #在结果的基础上再次查找 print(lilist.children("a.bb")) #在结果的基础上再次查找 print(doc("a.bb").parent()) #获取指定元素的直接父节点 #print(doc("a.bb").parents()) #获取指定元素的所有父节点 print(doc("a.bb").parent().siblings()) #获取兄弟节点 print("="*60) # 遍历: alist = doc("a") for a in alist.items(): print(a.attr.href) #print(a.attr('href')) #同上 print(a.text()) #获取内容 print(a.html()) #节点操作具体参考手册
第一页:https://movie.douban.com/top250?start=0
第二页:https://movie.douban.com/top250?start=25
第三页:https://movie.douban.com/top250?start=50
...
结果:
for i in range(10):
url = "https://movie.douban.com/top250?start="+str(i*25)
<div class="item">...</div>
中from requests.exceptions import RequestException from lxml import etree from bs4 import BeautifulSoup from pyquery import PyQuery as pq import requests import re,time,json def getPage(url): '''爬取指定url页面信息''' try: #定义请求头信息 headers = { 'User-Agent':'User-Agent:Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1' } # 执行爬取 res = requests.get(url,headers=headers) #判断响应状态,并响应爬取内容 if res.status_code == 200: return res.text else: return None except RequestException: return None def parsePage(content): '''解析爬取网页中的内容,并返回字段结果''' print(content) # =========使用pyquery解析================== # 解析HTML文档 doc = pq(content) #获取网页中所有标签并遍历输出标签名 items = doc("div.item") #遍历封装数据并返回 for item in items.items(): yield { 'index':item.find("div.pic em").text(), 'image':item.find("div.pic img").attr('src'), 'title':item.find("div.hd span.title").text(), 'actor':item.find("div.bd p:eq(0)").text(), 'score':item.find("div.bd div.star span.rating_num").text(), } ''' # =======使用Beautiful Soup解析==================== # 解析HTML文档 soup = BeautifulSoup(content,"lxml") #获取网页中所有标签并遍历输出标签名 items = soup.find_all(name="div",attrs={"class":"item"}) print(items) #遍历封装数据并返回 for item in items: yield { 'index':item.em.string, 'image':item.find(name="img",attrs={'width':'100'}).attrs['src'], 'title':item.find(name="span",attrs={'class':'title'}).string, 'actor':item.select("div.bd p")[0].get_text(), #内有标签使用string获取不到 'score':item.select("div.star span")[1].string, } ''' ''' # =======使用xpath解析==================== # 解析HTML文档,返回根节点对象 html = etree.HTML(content) #获取网页中所有标签并遍历输出标签名 items = html.xpath('//div[@class="item"]') #遍历封装数据并返回 for item in items: yield { 'index':item.xpath('.//div/em[@class=""]/text()')[0], 'image':item.xpath('.//img[@width="100"]/@src')[0], 'title':item.xpath('.//span[@class="title"]/text()')[0], 'actor':item.xpath('.//p[@class=""]/text()')[0], 'score':item.xpath('.//span[@class="rating_num"]/text()'), #'time':item[4].strip()[5:], } ''' def writeFile(content): '''执行文件追加写操作''' #print(content) with open("./result.txt",'a',encoding='utf-8') as f: f.write(json.dumps(content,ensure_ascii=False) + "\n") #json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False def main(offset): ''' 主程序函数,负责调度执行爬虫处理 ''' url = 'https://movie.douban.com/top250?start=' + str(offset) #print(url) html = getPage(url) #判断是否爬取到数据,并调用解析函数 if html: for item in parsePage(html): writeFile(item) # 判断当前执行是否为主程序运行,并遍历调用主函数爬取数据 if __name__ == '__main__': #main(0) for i in range(10): main(offset=i*25) time.sleep(1)
import requests from bs4 import BeautifulSoup from urllib.request import urlretrieve # 定义请求url地址 url = "https://list.jd.com/list.html?cat=9987,653,655" # 使用requests爬取指定url信息 res = requests.get(url) #print(res.text) # 使用BeautifulSoup创建解析器 soup = BeautifulSoup(res.text,"lxml") # 解析里面的所有商品图片 imlist = soup.find_all(name="img",attrs={"width":"220","height":"220"}) #print(len(imlist)) # 遍历并解析里面的图片url地址信息 m=1 for im in imlist: #首先判断有无src属性来决定如何获取 if 'src' in im.attrs: imurl = "https:"+im.attrs['src'] else: imurl = "https:"+im.attrs['data-lazy-img'] #储存图片(两种方式) # 使用urllib中urlretrieve直接存储图片 urlretrieve(imurl,'./mypic/p'+str(m)+'.jpg') ''' # 默认情况下,当您发出请求时,响应正文会立即下载,而设置stream参数为true,则只有响应头已经下载并且连接保持打开状态。 with requests.get(imurl, stream=True) as ir: # 使用with的好处不用考虑close关闭问题。 with open('./mypic/p'+str(m)+'.jpg', 'wb') as f: for chunk in ir: f.write(chunk) ''' print('p'+str(m)+'.jpg') m += 1
]
]
]
]
]
]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-89JW1AsE-1603719522341)(https://edu.csdn.net/notebook/python/images/week03/77.jpg)]]
用户请求的Headers
,用户行为
,网站目录和数据加载方式
。动态渲染页面信息爬取
。1)请求(客户端->服务端[request]) GET(请求的方式) /newcoder/hello.html(请求的目标资源) HTTP/1.1(请求采用的协议和版本号) Accept: */*(客户端能接收的资源类型) Accept-Language: en-us(客户端接收的语言类型) Connection: Keep-Alive(维护客户端和服务端的连接关系) Host: localhost:8080(连接的目标主机和端口号) Referer: http://localhost/links.asp(告诉服务器我来自于哪里) User-Agent: Mozilla/4.0(客户端版本号的名字) Accept-Encoding: gzip, deflate(客户端能接收的压缩数据的类型) If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT(缓存时间) Cookie(客户端暂存服务端的信息) Date: Tue, 11 Jul 2000 18:23:51 GMT(客户端请求服务端的时间) 2)响应(服务端->客户端[response]) HTTP/1.1(响应采用的协议和版本号) 200(状态码) OK(描述信息) Location: http://www.baidu.com(服务端需要客户端访问的页面路径) Server:apache tomcat(服务端的Web服务端名) Content-Encoding: gzip(服务端能够发送压缩编码类型) Content-Length: 80(服务端发送的压缩数据的长度) Content-Language: zh-cn(服务端发送的语言类型) Content-Type: text/html; charset=GB2312(服务端发送的类型及采用的编码方式) Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT(服务端对该资源最后修改的时间) Refresh: 1;url=http://www.it315.org(服务端要求客户端1秒钟后,刷新,然后访问指定的页面路径) Content-Disposition: attachment; filename=aaa.zip(服务端要求客户端以下载文件的方式打开该文件) Transfer-Encoding: chunked(分块传递数据到客户端) Set-Cookie:SS=Q0=5Lb_nQ; path=/search(服务端发送到客户端的暂存数据) Expires: -1//3种(服务端禁止客户端缓存页面数据) Cache-Control: no-cache(服务端禁止客户端缓存页面数据) Pragma: no-cache(服务端禁止客户端缓存页面数据) Connection: close(1.0)/(1.1)Keep-Alive(维护客户端和服务端的连接关系) Date: Tue, 11 Jul 2000 18:23:51 GMT(服务端响应客户端的时间)
import requests # 代理IP地址 proxy = {'HTTP':'117.85.105.170:808','HTTPS':'117.85.105.170:808'} # header头信息 headers = { 'Host': 'blog.csdn.net', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'http://www.baidu.com', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', } # 请求url地址 url = "http://blog.csdn.net" # 提交请求爬取信息 response = requests.get(url,headers=headers,proxies=proxy) # 获取响应码 print(response.status_code)
user_agents = [
'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
'Opera/9.25 (Windows NT 5.1; U; en)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7',
'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0',
]
import random
agent = random.choice(user_agents) # 随机获取一个浏览器用户信息
#爬取指定京东商品的评论信息 import requests import re # header头信息 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'http://www.baidu.com', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', } #请求url地址 url = "https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv14&productId=6045059&score=0&sortType=5&page=1&pageSize=10&isShadowSku=4687958&rid=0&fold=1" # 提交请求爬取信息 response = requests.get(url,headers=headers) #获取响应码 html = response.text pat = '"content":"(.*?)"' items = re.findall(pat,html,re.S) #print(items) for v in items: print(v) print("="*80)
pip install tesserocr #安装tesserocr pip install pillow # 图片处理目录 注意: 在mac下安装tesserocr ,需要先安装下面的软件 brew install tesseract --all-languages brew install imagemagick 在:Ubuntu、Debian 系统下先安装: sudo apt-get intall -y tesseract-ocr libtesseract-dev libleptonica-dev 在:CentOS、Red Hat 系统: yum install -y tesseract 在windows安装tesserocr前要先安装:tesseract 他是为tesserocr提供支持的 下载目录:https://digi.bib.uni-mannheim.de/tesseract/ 会有很多下载文件,下载一个3.0版本的exe文件即可 在安装中要勾选上Additional language data(download)选项来安装OCR识别支持的语言包
#验证识别测试
import tesserocr
from PIL import Image
#打开图片
image = Image.open("./code/5.png")
#识别验证码
result = tesserocr.image_to_text(image)
print(result)
#验证识别测试 import tesserocr from PIL import Image image = Image.open("./code/5.png") #将图片转化为灰度图像 image = image.convert("L") threshold = 127 table=[] for i in range(256): if i < threshold: table.append(0) else: table.append(1) image = image.point(table,'1') #识别验证码 result = tesserocr.image_to_text(image) print(result)
params = {
'offset': offset, #页码数据
'format': 'json',
'keyword': '街拍', #搜索关键字
'autoload': 'true',
'count': '20',
'cur_tab': '3',
'from': 'gallery',
}
import os,time import requests from urllib.parse import urlencode from urllib.request import urlretrieve def getPage(offset): '''爬取指定url页面信息''' params = { 'offset': offset, 'format': 'json', 'keyword': '街拍', 'autoload': 'true', 'count': '20', 'cur_tab': '3', 'from': 'gallery', } url = 'https://www.toutiao.com/search_content/?' + urlencode(params) try: response = requests.get(url) if response.status_code == 200: return response.json() except requests.ConnectionError: return None def getImages(json): '''解析获取图片信息''' data = json.get('data') if data: for item in data: # print(item) image_list = item.get('image_list') title = item.get('title') # print(image_list) for image in image_list: yield { 'image': image.get('url'), 'title': title } def saveImage(item): '''储存图片''' # 处理每组图片的存储路径 path = os.path.join("./mypic/",item.get('title')) if not os.path.exists(path): os.mkdir(path) # 拼装原图和目标图片的路径即名称 local_image_url = item.get('image') image_url = "http:"+local_image_url.replace('list','large') save_pic = path+"/"+local_image_url.split("/").pop()+".jpg" # 使用urllib中urlretrieve直接存储图片 urlretrieve(image_url,save_pic) def main(offset): ''' 主程序函数,负责调度执行爬虫处理 ''' json = getPage(offset) for item in getImages(json): print(item) saveImage(item) # 判断当前执行是否为主程序运行,并遍历调用主函数爬取数据 if __name__ == '__main__': #main(0) for i in range(5): main(offset=i*20) time.sleep(1)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。