爬虫流程复习2

1.打开网页
urllib.request.urlopen('网址')
例:response = urllib.request.urlopen('http://www.baidu.com/')
返回值为 <http.client.HTTPResponse object at 0x00000224EC2C9490>

2.获取响应头信息
urlopen 对象.getheaders()
例:response.getheaders()
返回值为 [('Bdpagetype', '1'), ('Bdqid', '0x8fa65bba0000ba44'),···,('Transfer-Encoding', 'chunked')]
[('','信息')]

3.获取响应头信息,带参数表示指定响应头
urlopen 对象.getheader('头信息')
例:response.getheader('Content-Type')
返回值为 'text/html;charset=utf-8'

4.查看状态码
urlopen 对象.status
例:response.status
返回值为 200 则表示成功

5.得到二进制数据,然后转换为 utf-8 格式
二进制数据
例:html = response.read()
HTML 数据格式
例:html = response.read().decode('utf-8')
打印输出时,使用 decode('字符集') 的数据 print(html.decode('utf-8'))

6.存储 HTML 数据
fp = open('文件名.html','模式 wb')
例:fp = open('baidu.html', 'wb')
fp.write(response.read() 对象)
例:fp.write(html)

7.关闭文件
open对象.close()
例:fp.close()

8.使用 ssl 进行抓取 https 的网页
例:
    import ssl
    content = ssl._create_unverified_context()
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}

    request = urllib.request.Request('http://www.baidu.com/', headers = headers)
    response = urllib.request.urlopen(request, context = context)
    这里的 response 就和上面一样了

9.获取码
response.getcode()
返回值为 200

10.获取爬取的网页 url
response.geturl()
返回值为 https://www.baidu.com/

11.获取响应的报头信息
response.info()
例:
    import ssl
    request = urllib.request.Request('http://www.baidu.com/', headers = headers)
    context = ssl._create_unverified_context()
    response = urllib.request.urlopen(request, context = context)
    response.info()
    获取的为 头信息
--
    response = urllib.request.urlopen('http://www.baidu.com/')
    response.info()
    返回值为 <http.client.HTTPMessage object at 0x00000268D453DA60>

12.保存网页
urllib.request.urlretrieve(url, '文件名.html')
例:urllib.request.urlretrieve(url, 'baidu.html')

13.保存图片
urllib.request.urlretrieve(url, '图片名.jpg')
例:urllib.request.urlretrieve(url, 'Dog.jpg')

其他字符(如汉字)不符合标准时,要进行编码
14.除了-._/09AZaz 都会编码
urllib.parse.quote()
例:
    Param = "全文检索:*"
    urllib.parse.quote(Param)
返回值为 '%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2%3A%2A'
参考链接:https://blog.csdn.net/ZTCooper/article/details/80165038

15.会编码 / 斜线(将斜线也转换为 %.. 这种格式)
urllib.parse.quote_plus(Param)

16.将字典拼接为 query 字符串 如果有中文,进行url编码
dic_object = {
    'user_name':'张三',
    'user_passwd':'123456'
}
urllib.parse.urlencode(dic_object)
返回值为 'user_name=%E5%BC%A0%E4%B8%89&user_passwd=123456'

17.获取 response 的行
url = 'http://www.baidu.com'
response = urllib.request.urlopen(url)
response.readline()

18.随机获取请求头(随机包含请求头信息的列表)
user_agent = [
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv2.0.1) Gecko/20100101 Firefox/4.0.1",
        "Mozilla/5.0 (Windows NT 6.1; rv2.0.1) Gecko/20100101 Firefox/4.0.1",
        "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
        "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"
]

ua = random.choice(user_agent)
headers = {'User-Agent':ua}

19.对输入的汉字进行 urlencode 编码
urllib.parse.urlencode(字典对象)
例:
chinese = input('请输入要查询的中文词语:')
wd = {'wd':chinese}
wd = urllib.parse.urlencode(wd)
返回值为 'wd=%E4%BD%A0%E5%A5%BD'

20.常见分页操作
for page in range(start_page, end_page + 1):
        pn = (page - 1) * 50

21.通常会进行拼接字符串形成网址
例:fullurl = url + '&pn=' + str(pn)

22.进行拼接形成要保存的文件名
例:filename = 'tieba/' + name + '贴吧_第' + str(page) + '页.html'

23.保存文件
with open(filename,'wb') as f:
    f.write(reponse.read() 对象)

24.headers 头信息可以删除的有
cookie、accept-encoding、accept-languag、content-lengthconnectionoriginhost

25.headers 头信息不可以删除的有
Accept、X-Requested-With、User-Agent、Content-Type、Referer

26.提交给网页的数据 formdata
formdata = {
    'from':'en',
    'to':'zh',
    'query':word,
    'transtype':'enter',
    'simple_means_flag':'3'
}

27.将formdata进行urlencode编码,并且转化为bytes类型
formdata = urllib.parse.urlencode(formdata).encode('utf-8')

28.使用 formdata 在 urlopen() 中
response = urllib.request.urlopen(request, data=formdata)

29.转换为正确数据(导包 json)

read -> decode -> loads -> json.dumps
通过read读取过来为字节码
data = response.read()
将字节码解码为utf8的字符串
data = data.decode('utf-8')
将json格式的字符串转化为json对象
obj = json.loads(data)
禁用ascii之后,将json对象转化为json格式字符串
html = json.dumps(obj, ensure_ascii=False)
json 对象通过 str转换后 使用 utf-8 字符集格式写入
保存和之前的方法相同
with open('json.txt', 'w', encoding='utf-8') as f:
    f.write(html)

30.ajax请求自带的头部
'X-Requested-With':'XMLHttpRequest'

31.豆瓣默认都得使用https来进行抓取,所以需要使用ssl模块忽略证书
例:
url = 'http://movie.douban.com/j/chart/top_list?type=24&interval_id=100%3A90&action='

page = int(input('请输入要获取页码:'))
start = (page - 1) * 20
limit = 20

key = {
    'start':start,
    'limit':limit
}

key = urllib.parse.urlencode(key)
url = url + '&' + key
headers = {
    'X-Requested-With':'XMLHttpRequest',
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
}

request = urllib.request.Request(url, headers=headers)

# context = ssl._create_unverified_context()
response = urllib.request.urlopen(request)

jsonret = response.read()

with open('douban.txt', 'w', encoding='utf-8') as f:
    f.write(jsonret.decode('utf-8'))
print('over')

32.创建处理 http 请求的对象
http_handler = urllib.request.HTTPHandler()

33.处理 https 请求
https_handler = urllib.request.HTTPSHandler()

34.创建支持http请求的opener对象
opener = urllib.request.build_opener(http_handler)

35.创建 reponse 对象
例:opener.open(Request 对象)
request = urllib.request.Request('http://www.baidu.com/')
reponse = opener.open(request)
进行保存
with open('文件名.html', 'w', encoding='utf-8') as f:
    f.write(reponse.read().decode('utf-8'))

36.代理服务器
http_proxy_handler = urllib.request.ProxyHandler({'https':'ip地址:端口号'})
例:http_proxy_handler = urllib.request.ProxyHandler({'https':'121.43.178.58:3128'})

37.私密代理服务器(下面的只是一个例子,不一定正确)
authproxy_handler = urllib.request.ProxyHandler({"http" : "user:password@ip:port"})

38.不使用任何代理
http_proxy_handler = urllib.request.ProxyHandler({})

39.使用了代理之后的 opener 写法
opener = urllib.request.build_opener(http_proxy_handler)

40.response 写法
response = opener.open(request)

41.如果访问一个不存在的网址会报错
urllib.error.URLError


42.HTTPError(是URLError的子类)
例:
try:
    urllib.request.urlopen(url)
except urllib.error.HTTPError as e:
    print(e.code)
    print(e.reason)
except urllib.error.URLError as e:
    print(e)

43.使用 CookieJar 创建一个 cookie 对象,保存 cookie 值
import http.cookiejar
cookie = http.cookiejar.CookieJar()

44.通过HTTPCookieProcessor构建一个处理器对象,用来处理cookie
cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
opener 的写法
opener = urllib.request.build_opener(cookie_handler)

45.使用 r'x'
d 表示转义字符  r'd' 表示 d

46.设置 正则模式
pattern = re.compile(r'规则', re.xxx )
pattern = re.compile(r'is(.*?),')
例:pattern = re.compile(r'LOVE', re.I)

47.match 只匹配开头字符
pattern.match('字符串'[,起始位置,结束位置])
例:m = pattern.match('i love you', 2, 6)
返回值为 <re.Match object; span=(2, 6), match='love'>

48. search 从开始匹配到结尾,返回第一个匹配到的
pattern.search('字符串')
例:m = pattern.search('i love you, do you love me, yes, i love')
返回值为 <re.Match object; span=(2, 6), match='love'>

49.findall 将匹配到的都放到列表中
pattern.findall('字符串')
例:m = pattern.findall('i love you, do you love me, yes, i love')
返回值为 ['love', 'love', 'love']

50.split 使用匹配到的字符串对原来的数据进行切割
pattern.split('字符串',次数)
例:m = pattern.split('i love you, do you love me, yes, i love me', 1)
返回值为 ['i ', ' you, do you love me, yes, i love me']
例:m = pattern.split('i love you, do you love me, yes, i love me', 2)
返回值为 ['i ', ' you, do you ', ' me, yes, i love me']
例:m = pattern.split('i love you, do you love me, yes, i love me', 3)
返回值为 ['i ', ' you, do you ', ' me, yes, i ', ' me']

51.sub 使用新字符串替换匹配到的字符串的值,默认全部替换
pattern.sub('新字符串','要匹配字符串'[,次数])
注:返回的是字符串
例:
string = 'i love you, do you love me, yes, i love me'
m = pattern.sub('hate', string, 1)
m 值为 'i hate you, do you love me, yes, i love me'

52.group 匹配组
m.group() 返回的是匹配都的所有字符
m.group(1) 返回的是第二个规则匹配到的字符
例:
string = 'i love you, do you love me, yes, i love me'
pattern = re.compile(r'is(.*?),')
m = pattern.match(string)
m.group()
返回值为 'i love you,'
m.group(1)
返回值为 'love you'

53.匹配标签
pattern = re.compile(r'<div class="thumb">(.*?)<img src=(.*?) alt=(.*?)>(.*?)</div>', re.S)

54.分离出文件名和扩展名,返回二元组
os.path.splitext(参数)
例:
获取路径
image_path = './qiushi'
获取后缀名
extension = os.path.splitext(image_url)[-1]

55.合并多个字符串
os.path.join()
图片路径
image_path = os.path.join(image_path, image_name + extension)
保存文件
urllib.request.urlretrieve(image_url, image_path)

56.获取 a 标签下的 href 的内容
pattern = re.compile(r'<a href="(.*?)" class="main_14" target="_blank">(.*?)</a>', re.M)
例:
import urllib.parse
import urllib.request
import re

class SmileSpider(object):
    """
    爬取笑话网站笑话的排行榜
    """
    def __init__(self, url, page=1):
        super(SmileSpider, self).__init__()
        self.url = url
        self.page = page

    def handle_url(self):
        '''
        处理url并且生成request请求对象
        '''
        self.url = self.url + '?mepage=' + str(self.page)
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
        }
        request = urllib.request.Request(self.url, headers=headers)
        return request

    def xiazai(self, request):
        '''
        负责下载数据,并且将数据返回
        '''
        response = urllib.request.urlopen(request)
        html = response.read().decode('gbk')
        return html

    def handle_data(self, data):
        '''
        开始处理数据,将段子抓取出来并且写入文件
        '''
        # 这个必须使用多行模式进行抓取,因为是抓取多个a链接
        pattern = re.compile(r'<a href="(.*?)" class="main_14" target="_blank">(.*?)</a>', re.M)
        # 找到所有的笑话链接
        alist = pattern.findall(data)
        # print(alist)
        # exit()
        print('开始下载')
        for smile in alist:
            # 获取标题
            # title = alist[14][1]
            title = smile[1]
            # 获取url
            # smile_url = alist[14][0]
            smile_url = smile[0]
            # 获取内容
            content = self.handle_content(smile_url)
            # 将抓取的这一页的笑话写到文件中
            with open('xiaohua.html', 'a', encoding='gbk') as f:
                f.write('<h1>' + title + '</h1>' + content)
        print('下载完毕')

    def handle_content(self, smile_url):
        # 因为有的href中有中文,所以必须先转码再拼接,如果先拼接再转码,就会将:也给转码了,不符合要求
        smile_url = urllib.parse.quote(smile_url)
        smile_url = 'http://www.jokeji.cn' + smile_url
        # print(smile_url)
        # exit()
        content = self.xiazai(smile_url)

        # 由于抓取的文本中,有的中间有空格,所以使用单行模式进行抓取
        pattern = re.compile(r'<span id="text110">(.*?)</span>', re.S)
        ret = pattern.search(content)
        return ret.group(1)

    def start(self):
        request = self.handle_url()
        html = self.xiazai(request)
        self.handle_data(html)


if __name__ == '__main__':
    url = 'http://www.jokeji.cn/hot.asp'
    spider = SmileSpider(url)
    spider.start()

57.href 中有中文的需要先进行转码,然后再拼接
smile_url = urllib.parse.quote(smile_url)
smile_url = 'http://www.jokeji.cn' + smile_url

58.导入 etree
from lxml import etree

59.实例化一个 html 对象,DOM模型
etree.HTML(通过requests库的get方法或post方法获取的信息 其实就是 HTML 代码)
例:html_tree = etree.HTML(text)
返回值为 <Element html at 0x26ee35b2400>
例:type(html_tree)
<class 'lxml.etree._Element'>

60.查找所有的 li 标签
html_tree.xpath('//li')

61.获取所有li下面a中属性href为link1.html的a
result = html_tree.xpath('//标签/标签[@属性="值"]')
例:result = html_tree.xpath('//li/a[@href="link.html"]')

62.获取最后一个 li 标签下 a 标签下面的 href 值
result = html_tree.xpath('//li[last()]/a/@href')

63.获取 class 为 temp 的结点
result = html_tree.xpath('//*[@class = "temp"]')

64.获取所有 li 标签下的 class 属性
result = html_tree.xpath('//li/@class')

65.取出内容
[0].text
例:result = html_tree.xpath('//li[@class="popo"]/a')[0].text
例:result = html_tree.xpath('//li[@class="popo"]/a/text()')

66.将 tree 对象转化为字符串
etree.tostring(etree.HTML对象).decode('utf-8')
例:
text = '''
<div>
    <ul>
         <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">third item</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>
     </ul>
 </div>
'''
html = etree.HTML(text)
tostring 转换的是bytes 类型数据
result = etree.tostring(html)
将 bytes 类型数据转换为 str 类型数据
print(result.decode('utf-8'))

67.动态保存图片,使用url后几位作为文件名
request = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(request)
html_tree = etree.HTML(html)
img_list = html_tree.xpath('//div[@class="box picblock col3"]/div/a/img/@src2')
for img_url in img_list:
    # 定制图片名字为url后10位
    file_name = 'image/' + img_url[-10:]
    load_image(img_url, file_name)
load_image内容:
def load_image(url, file_name):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    image_bytes = response.read()

    with open(file_name, 'wb') as f:
        f.write(image_bytes)
    print(file_name + '图片已经成功下载完毕')

例:
def load_page(url):
    headers = {
        #'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    print(url)
    # exit()
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    html = response.read()

    # 这是专业的图片网站,使用了懒加载,但是可以通过源码来进行查看,并且重新写xpath路径
    with open('7image.html', 'w', encoding='utf-8') as f:
        f.write(html.decode('utf-8'))
    exit()

    # 将html文档解析问DOM模型
    html_tree = etree.HTML(html)
    # 通过xpath,找到需要的所有的图片的src属性,这里获取到的
    img_list = html_tree.xpath('//div[@class="box picblock col3"]/div/a/img/@src2')
    for img_url in img_list:
        # 定制图片名字为url后10位
        file_name = 'image/' + img_url[-10:]
        load_image(img_url, file_name)

def load_image(url, file_name):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    image_bytes = response.read()

    with open(file_name, 'wb') as f:
        f.write(image_bytes)
    print(file_name + '图片已经成功下载完毕')
def main():
    start = int(input('请输入开始页面:'))
    end = int(input('请输入结束页面:'))
    url = 'http://sc.chinaz.com/tag_tupian/'
    for page in range(start, end + 1):
        if page == 1:
            real_url = url + 'KaTong.html'
        else:
            real_url = url + 'KaTong_' + str(page) + '.html'
        load_page(real_url)
        print('' + str(page) + '页下载完毕')

if __name__ == '__main__':
    main()

68.懒图片加载案例
例:
import urllib.request
from lxml import etree
import json

def handle_tree(html_tree):
    node_list = html_tree.xpath('//div[@class="detail-wrapper"]')
    duan_list = []
    for node in node_list:
        # 获取所有的用户名,因为该xpath获取的是一个span列表,然后获取第一个,并且通过text属性得到其内容
        user_name = node.xpath('./div[contains(@class, "header")]/a/div/span[@class="name"]')[0].text
        # 只要涉及到图片,很有可能都是懒加载,所以要右键查看网页源代码,才能得到真实的链接
        # 由于这个获取的结果就是属性字符串,所以只需要加上下标0即可
        face = node.xpath('./div[contains(@class, "header")]//img/@data-src')[0]
        # .代表当前,一个/表示一级子目录,两个//代表当前节点里面任意的位置查找
        content = node.xpath('./div[@class="content-wrapper"]//p')[0].text
        zan = node.xpath('./div[@class="options"]//li[@class="digg-wrapper "]/span')[0].text
        item = {
            'username':user_name,
            'face':face,
            'content':content,
            'zan':zan,
        }
        # 将其存放到列表中
        duan_list.append(item)

    # 将列表写入到文件中
    with open('8duanzi.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(duan_list, ensure_ascii=False) + '
')
    print('over')

def main():
    # 爬取百度贴吧,不能加上headers,加上headers爬取不下来
    url = 'http://neihanshequ.com/'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }
    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    html_bytes = response.read()

    # fp = open('8tieba.html', 'w', encoding='utf-8')
    # fp.write(html_bytes.decode('utf-8'))
    # fp.close()
    # exit()

    # 将html字节串转化为html文档树
    # 文档树有xpath方法,文档节点也有xpath方法 
    # 【注】不能使用字节串转化为文档树,这样会有乱码
    html_tree = etree.HTML(html_bytes.decode('utf-8'))

    handle_tree(html_tree)


if __name__ == '__main__':
    main()

69.  . / 和 // 在 xpath 中的使用
.代表当前目录
/ 表示一级子目录
// 代表当前节点里面任意的位置

70.获取内容的示范
获取内容时,如果为字符串,则不需要使用 text 只需要写[0]
face = node.xpath('./div[contains(@class, "header")]//img/@data-src')[0]
div 下 class"content-wrapper" 的所有 p 标签内容
content = node.xpath('./div[@class="content-wrapper"]//p')[0].text
div 下 class"options" 的所有 li 标签下 class为 "digg-wrapper" 的所有 span 标签内容
zan = node.xpath('./div[@class="options"]//li[@class="digg-wrapper"]/span')[0].text

71.将json对象转化为json格式字符串
f.write(json.dumps(duan_list, ensure_ascii=False) + '
')

72.正则获取 div 下的内容
1.获取 div 到 img 之间的数据
2.img 下 src 的数据
3.img 下 alt 的数据
4.一直到 div 结束的数据
pattern = re.compile(r'<div class="thumb">(.*?)<img src=(.*?) alt=(.*?)>(.*?)</div>', re.S)
pattern.方法 ,参考上面的正则

73.带有参数的 get 方式
import requests
params = {
    'wd':'中国'
}
r = requests.get('http://www.baidu.com/s?', headers=headers, params=params)
    requests.get 还可以添加 cookie 参数

74.设置编码
r.encoding='utf-8

75.查看所有头信息
r.request.headers

76.在 requests.get 方法中 url,params,headers,proxies 为参数
url 网址  params 需要的数据 headers 头部 proxies 代理

77.通过 Session 对象,发送请求
s = requests.Session()

78.发送请求
s.post(url,data,headers)

79.接收请求
s.get(url[,proxies])

80.当返回为 json 样式时
例:
city = input('请输入要查询的城市:')
params = {
    'city':city
}
r = requests.get(url, params=params)
r.json() 会打印出响应的内容

81.BeautifulSoup 创建对象
from bs4 import BeautifulSoup
soup = BeautifulSoup(open(url,encoding='utf-8),'lxml')

82.查找第一个<title> 标签
soup.title
返回值为 <title>三国猛将</title>

83.查找第一个 a 标签
soup.a
返回值为 <a class="aa" href="http://www.baidu.com" title="baidu">百度</a>

84.查找第一个 ul 标签
soup.ul

85.查看标签名字
a_tag = soup.a
a_tag.name
返回值为 a

86.查看标签内容
a_tag.attrs
返回值为 {'href': 'http://www.baidu.com', 'title': 'baidu', 'class': ['aa']}

87.获取找到的 a 标签的 href 内容(第一个 a)
soup.a.get('href')
返回值为 http://www.baidu.com

88.获取 a 标签下的 title 属性(第一个 a)
soup.a.get('title')
返回值为 baidu

89.查看 a 标签下的内容
soup.标签.string 标签还可以是 head、title等
soup.a.string
返回值为 百度

90.获取 p 标签下的内容
soup.p.string

91.查看 div 的内容,包含 '
'
soup.div.contents
返回值为
['
', <div class="div">
<a class="la" href="www.nihao.com">你好</a>
</div>, '
', <div>
<a href="www.hello.com">世界</a>
</div>, '
']

92.查看使用的字符集
soup.div.contents[1]
返回值为 <meta charset="utf-8"/>

93.查看body的子节点
soup.标签.children
例:soup.body.children
返回值是一个迭代对象,需要遍历输出
返回值为 <list_iterator object at 0x0000021863886C10>
for child in soup.body.children:
    print(child)
返回值为 body 中的所有内容

94.查看所有的子孙节点
soup.标签.descendants
例:soup.div.descendants
返回值为
<div class="div">
<a class="la" href="www.nihao.com">你好</a>
</div>
<a class="la" href="www.nihao.com">你好</a>
你好

95.查看所有的 a 标签
soup.find_all('a')
返回值为 包含所有的 a 标签的列表

96.查看 a 标签中第二个链接的内容
soup.find_all('a')[1].string

97.查看 a 标签中第二个链接的href值
soup.find_all('a')[1].href

98.将 re 正则嵌入进来,找寻所有以 b 开头的标签
soup.findall(re.compile('^b'))
返回值为 <body>标签 <b>

99.找到所有的 a 标签和 b 标签
soup.findall(re.compile(['a','b']))
返回值为 <a> 和 <b> 标签

100.通过标签名获取所有的 a 标签
soup.select('a')
返回值为 所有的 <a> 标签

101.通过 类名 获取标签(在 class 等于的值前面加 .)
soup.select('.aa')
返回值为 class='aa' 的标签

102.通过 id 名获取标签(在 id 等于的值前面加 #)
soup.select('#wangyi')
返回值为 id='wangyi'的标签

103.查看 div 下 class='aa' 的标签
soup.select('标签 .class 等于的值')
soup.select('div .aa')

104.查看 div 下,第一层 class='aa' 的标签
soup.select('.标签名 > .class= 的值')
soup.select('.div > .la')

105.根据属性进行查找,input 标签下class为 haha 的标签
soup.select('input[class="haha"]')

例:
import requests
from bs4 import BeautifulSoup
import json
import lxml

def load_url(jl, kw):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    }

    url = 'http://sou.zhaopin.com/jobs/searchresult.ashx?'
    params = {
        'jl':jl,
        'kw':kw,
    }
    # 自动完成转码,直接使用即可
    r = requests.get(url, params=params, headers=headers)

    handle_data(r.text)

def handle_data(html):
    # 创建soup对象
    soup = BeautifulSoup(html, 'lxml')
    # 查找职位名称
    job_list = soup.select('#newlist_list_content_table table')
    # print(job_list)
    jobs = []
    i = 1
    for job in job_list:
        # 因为第一个table只是表格的标题,所以要过滤掉
        if i == 1:
            i = 0
            continue
        item = {}
        # 公司名称
        job_name = job.select('.zwmc div a')[0].get_text()

        # 职位月薪
        company_name = job.select('.gsmc a')[0].get_text()
        # 工作地点
        area = job.select('.gzdd')[0].get_text()

        # 发布日期
        time = job.select('.gxsj span')[0].get_text()
        # 将所有信息添加到字典中
        item['job_name'] = job_name
        item['company_name'] = company_name
        item['area'] = area
        item['time'] = time
        jobs.append(item)

    # 将列表转化为json格式字符串,然后写入到文件中
    content = json.dumps(jobs, ensure_ascii=False)
    with open('python.json', 'w', encoding='utf-8') as f:
        f.write(content)
    print('over')

def main():
    # jl = input('请输入工作地址:')
    # kw = input('请输入工作职位:')
    load_url(jl='北京', kw='python')

if __name__ == '__main__':
    main()

106.将字典进行 json 转换为
import json
str_dict = {"name":"张三", "age":55, "height":180}
print(json.dumps(str_dict, ensure_ascii=False))
使用 ensure_ascii 输出则为 utf-8 编码

107.读取转换的对象,(注意 loads 和 load 方法)
json.loads(json.dumps 对象)
string = json.dumps(str_dict, ensure_ascii=False)
json.loads(string)
{"name":"张三", "age":55, "height":180}

108.将对象序列化之后写入文件
json.dump(字典对象,open(文件名.json,'w',encoding='utf-8,ensure_ascii=False))
json.dump(str_dict, open('jsontest.json', 'w', encoding='utf-8'), ensure_ascii=False)

109.转换本地的 json 文件转换为 python 对象
json.load(open('文件名.json',encoding='utf-8))

110.jsonpath 示例:
book.json文件
{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 12.99
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 8.99
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    }
}

import json
import jsonpath

obj = json.load(open('book.json', encoding='utf-8'))

所有book
book = jsonpath.jsonpath(obj, '$..book')
print(book)

所有book中的所有作者
authors = jsonpath.jsonpath(obj, '$..book..author')
print(authors)

book中的前两本书   '$..book[:2]'
book中的最后两本书 '$..book[-2:]'
book = jsonpath.jsonpath(obj, '$..book[0,1]')
print(book)

所有book中,有属性isbn的书籍
book = jsonpath.jsonpath(obj, '$..book[?(@.isbn)]')
print(book)

所有book中,价格小于10的书籍
book = jsonpath.jsonpath(obj, '$.store.book[?(@.price<10)]')
print(book)

2020-05-02

原文地址:https://www.cnblogs.com/hany-postq473111315/p/12819589.html