> 백엔드 개발 > 파이썬 튜토리얼 > Beautifulsoup과 Selenium의 사용법에 대한 간략한 소개

Beautifulsoup과 Selenium의 사용법에 대한 간략한 소개

巴扎黑
풀어 주다: 2017-07-20 09:42:52
원래의
2115명이 탐색했습니다.

Beautifulsoup 및 Selenium의 간단한 사용

요청 라이브러리 검토

저는 요청을 오랫동안 사용하지 않았습니다. 나중에 간단한 크롤러를 작성할 것이므로 조금만 작성하겠습니다. 검토. requests了,因为一会儿要写个简单的爬虫,所以还是随便写一点复习下。

import requests

r = requests.get('https://api.github.com/user', auth=('haiyu19931121@163.com', 'Shy18137803170'))print(r.status_code)  # 状态码200print(r.json())  # 返回json格式print(r.text)  # 返回文本print(r.headers)  # 头信息print(r.encoding)  # 编码方式,一般utf-8# 当写入文件比较大时,避免内存耗尽,可以一次写指定的字节数或者一行。# 一次读一行,chunk_size=512为默认值for chunk in r.iter_lines():print(chunk)# 一次读取一块,大小为512for chunk in r.iter_content(chunk_size=512):print(chunk)
로그인 후 복사

注意iter_linesiter_content返回的都是字节数据,若要写入文件,不管是文本还是图片,都需要以wb的方式打开。

Beautifulsoup的使用

进入正题,早就听说这个著名的库,以前写爬虫用正则表达式虽然不麻烦,但有时候会匹配不准确。使用Beautifulsoup可以准确从HTML标签中提取数据。虽然是慢了点,但是简单好使呀。

from bs4 import BeautifulSoup

html_doc = """<html><head><title>The Dormouse&#39;s story</title></head><body><p class="title"><b>The Dormouse&#39;s story</b></p><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.</p><p class="story">...</p>"""# 就注意一点,第二个参数指定解析器,必须填上,不然会有警告。推荐使用lxmlsoup = BeautifulSoup(html_doc, &#39;lxml&#39;)
로그인 후 복사

紧接着上面的代码,看下面一些简单的操作。使用点属性的行为,会得到第一个查找到的符合条件的数据。是find方法的简写。

soup.a
soup.find(&#39;p&#39;)
로그인 후 복사

上面的两句是等价的。

# soup.body是一个Tag对象。是body标签中所有html代码print(soup.body)
로그인 후 복사
<body>
<p class="title"><b>The Dormouse&#39;s story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body>
로그인 후 복사
# 获取body里所有文本,不含标签print(soup.body.text)# 等同于下面的写法soup.body.get_text()# 还可以这样写,strings是所有文本的生成器for string in soup.body.strings:print(string, end=&#39;&#39;)
로그인 후 복사
The Dormouse&#39;s story
Once upon a time there were three little sisters; and their names were
Elsie,
Lacie and
Tillie;
and they lived at the bottom of a well.
...
로그인 후 복사
# 获得该标签里的文本。print(soup.title.string)
로그인 후 복사
The Dormouse&#39;s story
로그인 후 복사
# Tag对象的get方法可以根据属性的名称获得属性的值,此句表示得到第一个p标签里class属性的值print(soup.p.get(&#39;class&#39;))# 和下面的写法等同print(soup.p[&#39;class&#39;])
로그인 후 복사
[&#39;title&#39;]
로그인 후 복사
# 查看a标签的所有属性,以字典形式给出print(soup.a.attrs)
로그인 후 복사
{&#39;href&#39;: &#39;http://example.com/elsie&#39;, &#39;class&#39;: [&#39;sister&#39;], &#39;id&#39;: &#39;link1&#39;}
로그인 후 복사
# 标签的名称soup.title.name
로그인 후 복사
title
로그인 후 복사

find_all

使用最多的当属find_all / find方法了吧,前者查找所有符合条件的数据,返回一个列表。后者则是这个列表中的第一个数据。find_all有一个limit参数,限制列表的长度(即查找符合条件的数据的个数)。当limit=1其实就成了find方法 。

find_all同样有简写方法。

soup.find_all(&#39;a&#39;, id=&#39;link1&#39;)
soup(&#39;a&#39;, id=&#39;link1&#39;)
로그인 후 복사

上面两种写法是等价的,第二种写法便是简写。

find_all(self, name=None, attrs={}, recursive=True, text=None,
             limit=None, **kwargs)
로그인 후 복사

name

name就是想要搜索的标签,比如下面就是找到所有的p标签。不仅能填入字符串,还能传入正则表达式、列表、函数、True。

# 传入字符串soup.find_all('p')# 传入正则表达式import re# 必须以b开头for tag in soup.find_all(re.compile("^b")):print(tag.name)# body# b# 含有t就行for tag in soup.find_all(re.compile("t")):print(tag.name)# html# title# 传入列表表示,一次查找多个标签soup.find_all(["a", "b"])# [The Dormouse&#39;s story,#  Elsie,#  Lacie,#  Tillie]
로그인 후 복사

传入True的话,就没有限制,什么都查找了。

recursive

调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False

# title不是html的直接子节点,但是会检索其下所有子孙节点soup.html.find_all("title")# [The Dormouse&#39;s story]# 参数设置为False,只会找直接子节点soup.html.find_all("title", recursive=False)# []# title就是head的直接子节点,所以这个参数此时无影响a = soup.head.find_all("title", recursive=False)# [The Dormouse&#39;s story]
로그인 후 복사

keyword和attrs

使用keyword,加上一个或者多个限定条件,缩小查找范围。

# 查看所有id为link1的p标签soup.find_all(&#39;a&#39;, id=&#39;link1&#39;)
로그인 후 복사

如果按类查找,由于class关键字Python已经使用。可以用class_,或者不指定关键字,又或者使用attrs填入字典。

soup.find_all(&#39;p&#39;, class_=&#39;story&#39;)
soup.find_all(&#39;p&#39;, &#39;story&#39;)
soup.find_all(&#39;p&#39;, attrs={"class": "story"})
로그인 후 복사

上面三种方法等价。class_可以接受字符串、正则表达式、函数、True。

text

搜索文本值,好像使用string参数也是一样的结果。

a = soup.find_all(text=&#39;Elsie&#39;)# 或者,4.4以上版本请使用texta = soup.find_all(string=&#39;Elsie&#39;)
로그인 후 복사

text参数也可以接受字符串、正则表达式、True、列表。

CSS选择器

还能使用CSS选择器呢。使用select方法就好了,select始终返回一个列表。

列举几个常用的操作。

# 所有div标签soup.select(&#39;div&#39;)# 所有id为username的元素soup.select(&#39;.username&#39;)# 所有class为story的元素soup.select(&#39;#story&#39;)# 所有div元素之内的span元素,中间可以有其他元素soup.select(&#39;div span&#39;)# 所有div元素之内的span元素,中间没有其他元素soup.select(&#39;div > span&#39;)# 所有具有一个id属性的input标签,id的值无所谓soup.select(&#39;input[id]&#39;)# 所有具有一个id属性且值为user的input标签soup.select(&#39;input[id="user"]&#39;)# 搜索多个,class为link1或者link2的元素都符合soup.select("#link1, #link2")
로그인 후 복사

一个爬虫小例子

上面介绍了requests和beautifulsoup4的基本用法,使用这些已经可以写一些简单的爬虫了。来试试吧。

此例子来自《Python编程快速上手——让繁琐的工作自动化》[美] AI Sweigart

这个爬虫会批量下载XKCD漫画网的图片,可以指定下载的页面数。

import osimport requestsfrom bs4 import BeautifulSoup# exist_ok=True,若文件夹已经存在也不会报错os.makedirs(&#39;xkcd&#39;)
url = &#39;https://xkcd.com/&#39;headers = {&#39;User-Agent&#39;: &#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) &#39;  &#39;Chrome/57.0.2987.98 Safari/537.36&#39;}def save_img(img_url, limit=1):
    r = requests.get(img_url, headers=headers)
    soup = BeautifulSoup(r.text, &#39;lxml&#39;)try:
        img = &#39;https:&#39; + soup.find(&#39;div&#39;, id=&#39;comic&#39;).img.get(&#39;src&#39;)except AttributeError:print(&#39;Image Not Found&#39;)else:print(&#39;Downloading&#39;, img)
        response = requests.get(img, headers=headers)with open(os.path.join(&#39;xkcd&#39;, os.path.basename(img)), &#39;wb&#39;) as f:for chunk in response.iter_content(chunk_size=1024*1024):
                f.write(chunk)# 每次下载一张图片,就减1limit -= 1# 找到上一张图片的网址if limit > 0:try:
            prev = &#39;https://xkcd.com&#39; + soup.find(&#39;a&#39;, rel=&#39;prev&#39;).get(&#39;href&#39;)except AttributeError:print(&#39;Link Not Exist&#39;)else:
            save_img(prev, limit)if __name__ == &#39;__main__&#39;:
    save_img(url, limit=20)print(&#39;Done!&#39;)
로그인 후 복사
Downloading 
Downloading 
Downloading 
Downloading 
Downloading 
Downloading 
Downloading 
Downloading 
Downloading 
...
Done!
로그인 후 복사

多线程下载

单线程的速度有点慢,比如可以使用多线程,由于我们在获取prev的时候,知道了每个网页的网址是很有规律的。它像这样。只是最后的数字不一样,所以我们可以很方便地使用range

import osimport threadingimport requestsfrom bs4 import BeautifulSoup

os.makedirs(&#39;xkcd&#39;)

headers = {&#39;User-Agent&#39;: &#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) &#39;  &#39;Chrome/57.0.2987.98 Safari/537.36&#39;}def download_imgs(start, end):for url_num in range(start, end):
        img_url = &#39;https://xkcd.com/&#39; + str(url_num)
        r = requests.get(img_url, headers=headers)
        soup = BeautifulSoup(r.text, &#39;lxml&#39;)try:
            img = &#39;https:&#39; + soup.find(&#39;div&#39;, id=&#39;comic&#39;).img.get(&#39;src&#39;)except AttributeError:print(&#39;Image Not Found&#39;)else:print(&#39;Downloading&#39;, img)
            response = requests.get(img, headers=headers)with open(os.path.join(&#39;xkcd&#39;, os.path.basename(img)), &#39;wb&#39;) as f:for chunk in response.iter_content(chunk_size=1024 * 1024):
                    f.write(chunk)if __name__ == &#39;__main__&#39;:# 下载从1到30,每个线程下载10个threads = []for i in range(1, 30, 10):
        thread_obj = threading.Thread(target=download_imgs, args=(i, i + 10))
        threads.append(thread_obj)
        thread_obj.start()# 阻塞,等待线程执行结束都会等待for thread in threads:
        thread.join()# 所有线程下载完毕,才打印print(&#39;Done!&#39;)
로그인 후 복사
iter_linesiter_content는 텍스트이든 이미지이든 파일을 작성하려면 다음을 수행해야 합니다. < 코드>wb 모드에서 열기로 시작하세요. 🎜🎜Using Beautifulsoup🎜🎜 본론으로 들어가겠습니다. 예전부터 이 유명한 라이브러리에 대해 들어본 적이 있습니다. 예전에는 크롤러를 작성할 때 정규식을 사용하는 것이 번거롭지 않았지만 때로는 일치가 정확하지 않을 수도 있었습니다. . Beautifulsoup를 사용하여 HTML 태그에서 데이터를 정확하게 추출하세요. 조금 느리기는 하지만 간단하고 사용하기 쉽습니다. 🎜🎜
from selenium import webdriverfrom selenium.webdriver.common.keys import Keysimport time

browser = webdriver.Chrome()# Chrome打开百度首页browser.get(&#39;https://www.baidu.com/&#39;)# 找到输入区域input_area = browser.find_element_by_id(&#39;kw&#39;)# 区域内填写内容input_area.send_keys(&#39;The Zen of Python&#39;)# 找到"百度一下"search = browser.find_element_by_id(&#39;su&#39;)# 点击search.click()# 或者按下回车# input_area.send_keys(&#39;The Zen of Python&#39;, Keys.ENTER)time.sleep(3)
browser.get(&#39;https://www.zhihu.com/&#39;)
time.sleep(2)# 返回到百度搜索browser.back()
time.sleep(2)# 退出浏览器browser.quit()
로그인 후 복사
로그인 후 복사
🎜🎜위 코드에 이어 아래의 몇 가지 간단한 작업을 살펴보세요. 포인트 속성을 사용하는 동작은 조건을 충족하는 첫 번째 발견 데이터를 가져옵니다. find 메소드의 약어입니다. 🎜🎜
browser.back()  # 返回按钮browser.forward() # 前进按钮browser.refresh()  # 刷新按钮browser.close()  # 关闭当前窗口browser.quit()  # 退出浏览器
로그인 후 복사
로그인 후 복사
🎜🎜위의 두 문장은 동일합니다. 🎜🎜
browser = webdriver.Chrome()
browser.get(&#39;https://passport.csdn.net/account/login&#39;)
browser.find_element_by_id(&#39;username&#39;).send_keys(&#39;haiyu19931121@163.com&#39;)
browser.find_element_by_id(&#39;password&#39;).send_keys(&#39;**********&#39;)
browser.find_element_by_class_name(&#39;logging&#39;).click()
로그인 후 복사
로그인 후 복사
🎜rrreee🎜rrreee🎜rrreee🎜rrreee🎜rrreee🎜rrreee🎜rrreee🎜rrreee🎜rrreee🎜rrreee🎜rrreee

find_all

🎜가장 많이 사용되는 방법은 의심할 여지 없이 find_all입니다. /찾기</code > method 글쎄, 전자는 조건에 맞는 데이터를 모두 찾아서 리스트를 돌려주는 방식이다. 후자가 이 목록의 첫 번째 데이터입니다. <strong><code>find_all에는 목록의 길이(즉, 발견된 조건을 충족하는 데이터의 수)를 제한하는 limit 매개변수가 있습니다. limit=1이면 실제로 find 메서드가 됩니다. 🎜🎜find_all에는 단축 메서드도 있습니다. 🎜🎜rrreee🎜🎜위의 두 가지 쓰기 방법은 동일하며, 두 번째 쓰기 방법은 약어입니다. 🎜rrreee

name

🎜name은 검색하려는 태그입니다. 예를 들어 다음은 모든 p 태그를 찾는 것입니다. 문자열을 채울 수 있을 뿐만 아니라 정규식, 목록, 함수 및 True를 전달할 수도 있습니다. 🎜🎜rrreee🎜🎜True를 전달하면 제한이 없으며 모든 항목이 검색됩니다. 🎜

재귀

🎜태그의 find_all() 메서드를 호출하면 BeautifulSoup은 현재 태그의 모든 하위 노드를 검색합니다. 태그에는 recursive=False 매개변수를 사용할 수 있습니다. 🎜🎜rrreee🎜

키워드 및 속성

🎜키워드를 사용하고 하나 이상의 한정어를 추가하여 검색 범위를 좁히세요. 🎜🎜rrreee🎜🎜클래스로 검색하면 Python에서는 class 키워드 때문에 이미 사용하고 있습니다. class_를 사용하거나 키워드를 지정하지 않거나 attrs를 사용하여 사전을 채울 수 있습니다. 🎜🎜rrreee🎜🎜위의 세 가지 방법은 동일합니다. class_는 문자열, 정규식, 함수 및 True를 허용할 수 있습니다. 🎜

text

🎜text 값을 검색해 보니 문자열 매개변수를 사용해도 같은 결과가 나오는 것 같습니다. 🎜🎜rrreee🎜🎜text 매개변수는 문자열, 정규 표현식, True 및 목록도 허용할 수 있습니다. 🎜

CSS 선택기

🎜CSS 선택기를 사용할 수도 있습니다. select 메소드를 사용하면 select는 항상 목록을 반환합니다. 🎜🎜몇 가지 일반적인 작업을 나열해 보세요. 🎜🎜rrreee🎜🎜작은 크롤러 예🎜🎜요청 및 beautifulsoup4의 기본 사용법은 위에 소개되어 있습니다. 이를 사용하면 이미 몇 가지 간단한 크롤러를 작성할 수 있습니다. 와서 시도해 보세요. 🎜
🎜이 예는 "Python 프로그래밍으로 빠르게 시작하기 - 번거로운 작업 자동화"에서 가져온 것입니다. [미국] AI Sweigart🎜
🎜이 크롤러는 XKCD Comics Network에서 그림을 일괄 다운로드하며 숫자를 지정할 수 있습니다. 다운로드할 페이지 수. 🎜🎜rrreee🎜rrreee🎜멀티 스레드 다운로드🎜🎜싱글 스레드의 속도는 약간 느립니다. 예를 들어 멀티 스레드를 사용할 수 있습니다. prev를 받으면 URL을 알 수 있기 때문입니다. 각 웹페이지의 내용은 매우 규칙적입니다. 이렇습니다. 마지막 숫자만 다르므로 range를 사용하여 쉽게 탐색할 수 있습니다. 🎜🎜rreee🎜

来看下结果吧。

Beautifulsoup과 Selenium의 사용법에 대한 간략한 소개

初步了解selenium

selenium用来作自动化测试。使用前需要下载驱动,我只下载了Firefox和Chrome的。网上随便一搜就能下载到了。接下来将下载下来的文件其复制到将安装目录下,比如Firefox,将对应的驱动程序放到C:\Program Files (x86)\Mozilla Firefox,并将这个路径添加到环境变量中,同理Chrome的驱动程序放到C:\Program Files (x86)\Google\Chrome\Application并将该路径添加到环境变量。最后重启IDE开始使用吧。

模拟百度搜索

下面这个例子会打开Chrome浏览器,访问百度首页,模拟输入The Zen of Python,随后点击百度一下,当然也可以用回车代替。Keys下是一些不能用字符串表示的键,比如方向键、Tab、Enter、Esc、F1~F12、Backspace等。然后等待3秒,页面跳转到知乎首页,接着返回到百度,最后退出(关闭)浏览器。

from selenium import webdriverfrom selenium.webdriver.common.keys import Keysimport time

browser = webdriver.Chrome()# Chrome打开百度首页browser.get(&#39;https://www.baidu.com/&#39;)# 找到输入区域input_area = browser.find_element_by_id(&#39;kw&#39;)# 区域内填写内容input_area.send_keys(&#39;The Zen of Python&#39;)# 找到"百度一下"search = browser.find_element_by_id(&#39;su&#39;)# 点击search.click()# 或者按下回车# input_area.send_keys(&#39;The Zen of Python&#39;, Keys.ENTER)time.sleep(3)
browser.get(&#39;https://www.zhihu.com/&#39;)
time.sleep(2)# 返回到百度搜索browser.back()
time.sleep(2)# 退出浏览器browser.quit()
로그인 후 복사
로그인 후 복사

Beautifulsoup과 Selenium의 사용법에 대한 간략한 소개

send_keys模拟输入内容。可以使用element的clear()方法清空输入。一些其他模拟点击浏览器按钮的方法如下

browser.back()  # 返回按钮browser.forward() # 前进按钮browser.refresh()  # 刷新按钮browser.close()  # 关闭当前窗口browser.quit()  # 退出浏览器
로그인 후 복사
로그인 후 복사

查找方法

以下列举常用的查找Element的方法。

方法名返回的WebElement
find_element_by_id(id)匹配id属性值的元素
find_element_by_name(name)匹配name属性值的元素
find_element_by_class_name(name)匹配CSS的class值的元素
find_element_by_tag_name(tag)匹配标签名的元素,如div
find_element_by_css_selector(selector)匹配CSS选择器
find_element_by_xpath(xpath)匹配xpath
find_element_by_link_text(text)完全匹配提供的text的a标签
find_element_by_partial_link_text(text)提供的text可以是a标签中文本中的一部分

登录CSDN

以下代码可以模拟输入账号密码,点击登录。整个过程还是很快的。

browser = webdriver.Chrome()
browser.get(&#39;https://passport.csdn.net/account/login&#39;)
browser.find_element_by_id(&#39;username&#39;).send_keys(&#39;haiyu19931121@163.com&#39;)
browser.find_element_by_id(&#39;password&#39;).send_keys(&#39;**********&#39;)
browser.find_element_by_class_name(&#39;logging&#39;).click()
로그인 후 복사
로그인 후 복사

Beautifulsoup과 Selenium의 사용법에 대한 간략한 소개

以上差不多都是API的罗列,其中有自己的理解,也有照搬官方文档的。


by @sunhaiyu

2017.7.13

위 내용은 Beautifulsoup과 Selenium의 사용법에 대한 간략한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿