一、基础库urllib
方法 | 含义 | 用法 |
---|---|---|
urllib.request.urlopen(url) | 这个方法就是访问指定的url | response=urllib.request.urlopen(url)其中response是访问返回的源码,但源码不是utf-8格式的 |
response.read() | 返回读取的源码 | content = response.read(),由于response不是utf-t格式的,如果直接读取会很乱,所以一般都在读之后转码 |
response.read().decode(‘utf-8’) | 返回读取的源码的转码形式 | content=response.read().decode(‘utf-8’)。此时读取的是utf-8格式的内容。 |
response.status | 返回内容爬取是否正确,正确是200 | print(response.status) |
response.getheaders() | 返回所有的头信息 | print(response.getheaders()) |
response.getheader(name) | 返回指定的头信息 | print(response.getheader(‘Server’))这样的话,会打印指定的头信息Server |
urllib.request.Request(url) | 返回Request类型的对象 | req = urllib.request.Request(url)。这样的目的是将其封装成Request对象,可以添加一些请求的信息,比如修改User-Agent,请求字典,请求类型等。 |
urllib.request.Request(url,date={},headers=’’) | 返回Request类型的对象 | req =urllib.request.Request(url,date={},headers=’’)。这样的目的是将其封装成Request对象,可以添加一些请求的信息,比如修改User-Agent,请求字典,请求类型等,只是与之前不同的是,直接在定义的时候添加 |
req.add_信息类型(信息) | 给req添加一个请求信息 | req.add_header(‘User_Agent’,‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36’)类似这样,也就是在req的定义所需要的额外的信息没有被定义的时候添加时,就可以手动添加 |
urllib.parse.urlencode(data).encode(‘utf-8’) | 将需要发送的字典转成网页需要的utf-8格式 | date=urllib.parse.urlencode(data).encode(‘utf-8’)。这个是将所要post的字典由字典类型转成网页所需要的utf-8类型 |
案例代码展示:
翻译爬虫post
#导入三个模块,分别是:
#request模块用来访问地址
#parse模块用来将请求正文的data字典从原本形式即utf-8封装起来.
#json模块将read获得的字符串形式变成字典形式
import urllib.request
import urllib.parse
import json
#输入要翻译的文字
tarslate=input('你要翻译的是:')
#翻译的请求url(即爬虫要找到的地址)赋给url(自定义的变量)
url='http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
#创建一个字典用来收纳请求正文的字典
data={}
#将请求正文的各个内容用字典形式保存在data 中,其中i的值要改成自定义要翻译的变量
data['action']= 'FY_BY_CLICKBUTTION'
data['client']='fanyideskweb'
data['doctype']='json'
data['from']='AUTO'
data['i']=tarslate
data['keyfrom']='fanyi.web'
data['salt']='1536061146665'
data['sign']='156a72f2e9a7e3e1dc040cce61ed7eb2'
data['smartresult']='dict'
data['to']='AUTO'
data['typoResult']='false'
data['version']='2.1'
#此时的data 字典还不能被直接访问传入,因为要求是applaction格式,需要用urllib.parse.urlencode来给他转码一下,编码形式用encode('utf-8')来封装(即将原先是utf-8形式变成一种爬虫抓取的编码形式)再重新赋给data
data=urllib.parse.urlencode(data).encode('utf-8')
#调用urllib.request.urlopen来访问地址,其中有data 表示用post形式
response=urllib.request.urlopen(url,data)
#获取后的response拥有得到的地址的操作,可以用read()来读取,此时读取的是二进制编码,需要用decode('utf-8')来解封成utf-8即原先网页显示的形式
html=response.read().decode('utf-8')
#因为是用data字典来访问获取的,得到的是一个字符串形式的字典(即json格式),不宜被用户观看,需要调用json的loads()来将它转成字典形式
target=json.loads(html)
#打印出来,即选择出字典中对应的关键字的被翻译的值所在的地方
print('结果是%s' %(target['translateResult'][0][0]['tgt']))
input('')
图片爬取爬虫,GET
import urllib.request
import os
def get_url(url):
req=urllib.request.Request(url)
req.add_header('User_Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36')
response=urllib.request.urlopen(url)
html=response.read()
print(url)
return html
def get_num(html):
html=html.decode('utf-8')
a=html.find('current-comment-page')+23
b=html.find(']',a)
nums=html[a:b]
return nums
def get_picture(html):
html=html.decode('utf-8')
picture_list=[]
a=html.find('img src=')
print(a)
while a!=-1:
b=html.find('.jpg',a,a+255)
print(b)
if b!=-1:
picture_list.append(html[a+9:b+4])
else :
b=a+9
a=html.find('img src=',b)
for each in picture_list:
prinf(each)
def in_file(folder,html,i):
with open ('D://图片//1' %i,'wb') as f:
f.write(html)
def download_picture(folder='picture',page=10):
os.mkdir(folder)
os.chdir(folder)
url='https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/02/0E/ChMkJ1w9tMqIEr5sABaSMmZkIzwAAuZvQHkBxMAFpJK682.jpg'
html=get_url(url)
this_num=int(get_num(html))
for i in range(page):
this_num+=i
page_url=url+'page-'+str(this_num)+'#comments'
html=get_url(page_url)
get_picture(html)
download_picture()
标题二、升级库requests库(搭配正则表达式re,与解析库Beautiful Soup4)
方法 | 含义 | 用法 |
---|---|---|
requests.get(url) | 以get的方式来访问网址 | response = requests.get(url)这将返回使用get方式获取的网址的源码 |
response.text | 返回源码的内容,正常来说是已经转码过的 | text = response.text |
requests.post(url,其他选项) | 以post的方式来访问网站 | response = requests.post(url,datas…)这个的意思是以post的形式来访问,并且附带一些要post的内容 |
response.status_code | 返回的是爬取的状态码 | 200表示成功没有出错 |
在GET和POST中,可以添加的辅助信息
params : 字典或字节序列,作为参数增加到 url 中
data : 字典、字节序列或文件对象,作为 Request 的内容
json : JSON 格式的数据,作为 Request 的内容
headers : 字典,HTTP 定制头
cookies : 字典或 CookieJar, Request 中的 cookie
auth : 元组,支持 HTTP 认证功能
files : 字典类型,传输文件
timeout : 设定超时时间,秒为单位
proxies : 字典类型,设定访问代理服务器,可以增加登录认证
allow_redirects : True/False,默认为 True,重定向开关
stream : True/False, 默认为 True, 获取内容立即下载开关
verify : True/False, 默认为 True, 认证 SSL 证书开关
cert : 本地 SSL 证书路径
使用案例GET:
import requests
url='http://www.cntour.cn/'
info=requests.get(url)
print(info.text)
使用案例POST
import requests
import json
print('输入要翻译的内容')
a=input(":")
url='http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
datas={'i':a,
'from':'AUTO',
'to':'AUTO',
'smartresult':'dict',
'client':'fanyideskweb',
'salt':'15437410255351',
'sign':'a65df43d575ebfebe56eed6dfba6d75e',
'ts':'1543741025535',
'bv':'37074a7035f34bfbf10d32bb8587564a',
'doctype':'json',
'version':'2.1',
'keyfrom':'fanyi.web',
'action':'FY_BY_REALTIME',
'typoResult':'false'}
#print(datas)
info=requests.post(url,datas)
print(info.text)
infos=json.loads(info.text)
print(infos)
#traslate=info['translateResult'][0][0]['tgt']
print(infos['translateResult'][0][0]['tgt'])
Beautiful Soup4的使用方法:
超全官方文档:
https://beautifulsoup.readthedocs.io/zh_CN/latest/
自己的总结:
1、首先将抓取的内容通过Beautifulsoup库实例化一个bs4对象
- soup=BeautifulSoup(markup, “html.parser”)解析网址返回信息,并选择解析器生成soup对象
- 其中,markup是爬取的内容,html.parser是使用的解析器。解析器有四种,优劣各不一样,一般就用html.parser即可
2、通过soup获取数据的方法
soup的方法 | 示例 | 含义 |
---|---|---|
soup.prettify() | soup.prettify() | 返回的是soup解析的H5格式的全内容 |
soup.标签 | soup.title | 返回的是指定标签第一个匹配项的全部内容(标签+内容) |
soup.标签.name | soup.title.name | 返回指定标签的第一个匹配项的的标签名 |
soup.标签.string | soup.title.string | 返回指定标签第一个匹配项的内容 |
soup.get_text() | soup.get_text() | 返回的是所有爬取信息的所有去标签内容 |
soup.标签[] | soup.title[id] | 返回指定标签匹配的第一个项的[]内的值,比如id class要写成class_ |
soup.find(条件) | soup.find(id=1000),条件可以是id,或者是标签名(只是标签名要用’'包起来) | 返回指定条件的第一个项的对象,接下来就可以获得name,string等 |
soup.find_all(条件) | soup.find_all(‘p’),条件可以是id,或者标签名(只是标签名要用’'包起来) | 返回的是指定条件的所有项对象,使用列表来容纳它们。 |
tag = soup.标签 | tag = soup.标签 | 返回的是第一个匹配的标签对象 |
tag.string | print(tag.string) | 返回标签对应的内容 |
tag.name | print(tag.name) | 返回的是标签对应的名字 |
tag.contents | tags = tag.contents | 返回以列表形式的子标签 |
tag.children | for i in soup.标签.children: | tag.children是一个字标签的生成器 |
BS4的案例:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import re
import requests
import bs4
import json
import MainUtil
# 相对路径,也是需要将此路径存入数据库
resources_file_path = '/resources/movie/cinemaNameList.ini'
scratch_url = 'http://theater.mtime.com/China_Beijing/'
# scratch data with define url
def scratch_latest_movies(scratch_url, old_movies):
data = requests.get(scratch_url).text
soup = bs4.BeautifulSoup(data, "html.parser")
new_movies = []
new_movies_json = json.loads(
soup.find('script', text=re.compile("var hotplaySvList")).text.split("=")[1].replace(";", ""))
coming_movies_data = soup.find_all('li', class_='i_wantmovie')
# 上映的电影
for movie in new_movies_json:
move_name = movie['Title']
if move_na
me not in old_movies:
new_movies.append(movie['Title'])
# 即将上映的电影
for coming_movie in coming_movies_data:
coming_movie_name = coming_movie.h3.a.text
if coming_movie_name not in old_movies and coming_movie_name not in new_movies:
new_movies.append(coming_movie_name)
return new_movies
if __name__ == '__main__':
MainUtil.main(resources_file_path, scratch_url, scratch_latest_movies)