目录

爬虫流程及方法02(Beautiful Soup解析页面)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python3

#对某论坛的爬取
import requests
from bs4 import BeautifulSoup
import time
#需求:爬取网站标题及详情页的文本

a = True
while a:#可转变成实时循环#对首页的页面数据进行爬取
    url = "https://www.lolichan.vip/"
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'
    }
    page_text = requests.get(url=url, headers=headers).text#获取响应数据得加text,不然获取的是响应对象
    #在首页中解析出章节标题和详情页URL
    #1.实例化BeautifulSoup对象,需要将页面源码加载到该对象中
    soup = BeautifulSoup(page_text, 'lxml')
    #解析章节标题与详情页url
    div_list = soup.select('.node-body > div > h3 > a')#使用select层级选择器
    fp = open('./xiangqing.text','w',encoding='utf-8')#创建文档及设定只写w和编码utf-8
    for div in div_list:
        time.sleep(填入休息时间)#防止频繁的请求链接失去响应
        title = div.string#获得该标签下的所有文本
        detail_url = 'https://www.lolichan.vip/' + div['href']#获得详情页的url
        #对详情页发起请求,解析出章节内容
        detail_page_text = requests.get(url=detail_url, headers=headers).text
        #解析出详情页中相关的章节内容
        detail_soup = BeautifulSoup(detail_page_text,'lxml')
        div_tag  = detail_soup.select('.structItem-title > a')
        #原来的class属性得用class_表示,不然会报错(class是保留字)
        content = []#设定空列表
        for a in div_tag:
            content.append(a.text)#往空列表内装填
        fp.write(title+':'+str(content)+'\n')#str()使content对象变为字符串形式
        print(title, '爬取成功')#响应成功
    a = False

#号符号是python注释的前置符号

pycharm的热键: ctrl+z 键回撤你的对代码的改动 ctrl+/键注释与代码的转换 ctrl+c复制 ctrl+v粘贴

1
2
3
#!/usr/bin/env python3
soup.tagName
    print(soup.meta)#第一组a标签 

soup.tagName返回的是html中第一次出现的tagName标签

1
2
3
#!/usr/bin/env python3
soup.find
    print(soup.find('meta'))=print(soup.meta)
属性定位,定位一定class加空格再=  #属性可以是class 或id 或attr
1
2
#!/usr/bin/env python3
print(soup.find('div', class = 'song'))
1
2
#!/usr/bin/env python3
soup.find_all('tagName')

找到符合标准的所有标签,返回一个列表

1
2
#!/usr/bin/env python3
print(soup.find_all('meta'))
1
2
#!/usr/bin/env python3
select('某种选择器').

表示class类选择器 id选择器 标签选择器
返回的是一个列表

1
2
#!/usr/bin/env python3
soup.select('xx >  xx  xx')

1
2
#!/usr/bin/env python3
soup.select('xx >  xx > xx')
1
2
#!/usr/bin/env python3
print(soup.select('.tang'))#<div class='tang'>

部分html代码

1
2
3
4
5
 <div class='tang'>
        <ul>
            <li><a href="http://...." title="qingming">mutongyao</a></li>
            <li><a href="http://...." title="chunjie">...</a></li>
        <ul>
1
print(soup.select('.tang > ul > li > a'))

结果:

1
2
<a href="http://...." title="qingming">...</a>,
<a href="http://...." title="chunjie">...</a>

层级选择器:此时返回一个列表,此时'.class的内容 > ul > li > a’中大于号>表示一个层级

1
2
3
4
#!/usr/bin/env python3
    print(soup.select('.tang > ul > li > a')[0])
    #结果:<a href="http://...." title="qingming">mutongyao</a>
    #多个层级'.tang > ul a' 这里空格表示多个层级,大于号>表示一个层级
1
2
#!/usr/bin/env python3
    print(soup.select('.tang > ul > li > a')[0])=print(soup.select('.tang > ul a')[0])

获取标签之间的文本数据

1
2
3
#!/usr/bin/env python3
    soup.a.text/string/get_text()
    print(soup.select('. class的内容> ul a')[0].text)

结果:

1
mutongyao
1
2
#!/usr/bin/env python3
    text/get_text()

get_text()可以获取一个标签中‘所有的’文本内容(即使不属于该标签直系文本内容)

string:只可以获得该标签下直系文本内容

获取标签中的属性值

1
2
#!/usr/bin/env python3
print(soup.select('.class的内容 > ul a')[0]['href'])

下行遍历(这里两个方法必须是循环中使用)

1
2
3
#!/usr/bin/env python3
for child in soup.body.children:
   print(child)

遍历儿子节点

1
2
3
#!/usr/bin/env python3
for child in soup.body.descendants:
   print(child)

遍历子孙节点

上行遍历

1
2
3
#!/usr/bin/env python3
for sibling in soup.a.next_siblings:
    print(sibling)

遍历后续节点

1
2
3
#!/usr/bin/env python3
for sibling in soup.a.previous_siblings:
    print(sibling)

遍历前续节点

1
soup.prettify()

每个节点一个换行符

1
<> .find_all(name, attrs, recursive, string, **kwargs)

返回一个列表类型,存储查找的结果。

name:对标签名称的检索字符串。
attrs:对标签属性值的检索字符串,可标注属性检索。
recursive:是否对子孙全部检索,默认True。
string: <>…</>中字符串区域的检索字符串。