初见网络爬虫
in Web Crawler 访问: 739 次 with 0 comment

初见网络爬虫

in Web Crawler with 0 comment

lmQYzUvOoK0.jpg

初见网络爬虫

网络链接

from urllib.request import urlopen

html = urlopen("http://pythonscraping.com/pages/page1.html")

print(html.read())

urlopen 用来打开并读取一个从网络获取的远程对象。

BeautifulSoup

通过定位 HTML 标签来格式化和组织复杂的网络信息,用简单易用的 Python 对象为我们展现 XML 结构信息

#scrapetest.py
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("http://pythonscraping.com/pages/page1.html")
bsObj = BeautifulSoup(html.read())
print(bsObj.h1)

任何 HTML(或XML)文件的任意节点信息都可以被提取出来,只要目标信息的旁边或附近有标记就行。

#scrapetest.py
from urllib.request import urlopen
from bs4 import BeautifulSoup

def getTitle(url):
    try:
        html = urlopen(url)
    except HTTPError as e:
        return None

    try:
        bsObj = BeautifulSoup(html.read(),"html.parser")
        title = bsObj.body.h1
    except AttributeError as e:
        return None

    return title

title = getTitle("http://www.pythonscraping.com/pages/page1.html")
if title == None:
    print("Title could not be found")
else:
    print(title)

复杂HTML解析

不是一直都要用锤子

1.看看网站有没有 HTML 样式更友好的移动版 的请求头设置成处于移动设备的状态,然后接收网站移动版 2.寻找隐藏在 JavaScript 文件里的信息

再端一碗BeautifulSoup

CSS 的发明却是网络爬虫的福音。CSS 可以让 HTML 元素呈现出差异化, 使那些具有完全相同修饰的元素呈现出不同的样式。

<span class="green"></span>
<span class="red"></span>

网络爬虫可以通过 class 属性的值,轻松地区分出两种不同的标签。

用 findAll 函数抽取只包含在<span class="green"></span> 标签里的文字

#scrapetest.py
from urllib.request import urlopen
from bs4 import BeautifulSoup

def get_namelist(url):
    try:
        html = urlopen(url)
    except HTTPError as e:
        return None

    try:
        bs_obj = BeautifulSoup(html,"html.parser")
        name_list = bs_obj.findAll("span",{"class":"green"})
    except AttributeError as e:
        return None

    return name_list

name_list = get_namelist("http://www.pythonscraping.com/pages/warandpeace.html")
if name_list == None:
    print("namelist could not be found")
else:
    for name in name_list:
        print(name.get_text())

调用 bsObj.findAll(tagName, tagAttributes) 可以获取页面中所有指定的标签。

.get_text() 会把你正在处理的 HTML 文档中所有的标签都清除,然后返回
一个只包含文字的字符串。把这些超链接、段落和标签都清除掉,只剩下一串不带标签的文字。

find()和findAll()
findAll(tag, attributes, recursive, text, limit, keywords)
find(tag, attributes, recursive, text, keywords)

标签参数 tag可以传一个标签的名称或多个标签名称组成的 Python 列表做标签参数

属性参数 attributes 是用一个 Python 字典封装一个标签的若干属性和对应的属性值。

递归参数 recursive 是一个布尔变量

如果recursive 设置为 True,findAll 就会根据你的要求去查找标签参数的所有子标签,以及子标签的子标签。如果 recursive 设置为 False,findAll 就只查找文档的一级标签。

文本参数 text 用标签的文本内容去匹配,而不是用标签的属性。

关键词参数 keyword,可以让你选择那些具有指定属性的标签。

导航树
处理子标签和后代标签

子标签就是一个父标签的下一级,而后代标签是指一个父标签下面所有级别的标签

所有的子标签都是后代标签,但不是所有的后代标签都是子标签。

BeautifulSoup 函数总是处理当前标签的后代标签

只想找出子标签,可以用 .children 标签

#scrapetest.py
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bs_obj = BeautifulSoup(html,"lxml")

for child in bs_obj.find("table",{"id":"giftList"}).children:
    print(child)

处理兄弟标签

#scrapetest.py
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bs_obj = BeautifulSoup(html,"lxml")

for sibling in bs_obj.find("table",{"id":"giftList"}).tr.next_siblings:
    print(sibling)

任何时候你获取一个标签的兄弟标签,都不会包含这个标签本身。这个函数只调用后面的兄弟标签。

next_sibling 和 previous_sibling 函数,与 next_siblings 和 previous_siblings的作用类似,只是它们返回的是单个标签,而不是一组标签

正则表达式

 *        匹配前面的字符、子表达式或括号里的字符 0 次 或多次
+        匹配前面的字符、子表达式或括号里的字符至少 1次
[]        匹配任意一个字符(相当于“任选一个”)
()        表达式编组(在正则表达式的规则里编组会优先运行)
{m,n}    匹配前面的字符、子表达式或括号里的字符 m 到 n 次(包含 m 或 n)
[^]        匹配任意一个不在中括号里的字符
|        匹配任意一个由竖线分割的字符、子表达式(注意是竖线,不是大字字母 I)
.        匹配任意单个字符(包括符号、数字和空格等)
^        指字符串开始位置的字符或子表达式
\        转义字符(把有特殊含义的字符转换成字面形式)

邮箱的正则表达式

[A-Za-z0-9\._+]+@[A-Za-z0-9]+\.(com|org|edu|net)
正则表达式和BeautifulSoup
#scrapetest.py
from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bs_obj = BeautifulSoup(html,"lxml")
images = bs_obj.findAll("img",{"src":re.compile("\.\.\/img\/gifts\/img.*\.jpg")})
for image in images:
    print(image["src"])
import re
re.compile("正则表达式")
Responses