一些必要的第三方庫
beautifulsoup4
bs4
lxml
requests
request庫 的用法
1.用于構建一個請求 request.Request
原型:request = urllib.request.Request(url = url,data = data,headers = headers,method = ‘POST’)
實體:
rq = request.Request(url, headers=header)
回傳型別為 urllib.request.Request
2.對目標url的訪問函式 request.urlopen()
原型:request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
實體:
resp = request.urlopen(rq)
但是請求后并不是字符型別,是 http.client.HTTPResponse 型別
3.對 resp 進行解碼
result = resp.read().decode('utf-8')
4.result 得到網頁原始碼,通過 decode() 解碼完成后為 str 型別,
如果需要使用 BeautifulSoup 對網頁進行資訊提取,需要使用
soup = BeautifulSoup(result, 'lxml')
將 str 型別的回傳結果轉化成 BeautifulSoup 物件,
另:request.get()請求
params 接收一個字典或者字串的查詢引數,字典型別自動轉換為url編碼,不需要urlencode()
實體:
response = requests.get(url,headers=headers,params=kw)
XPath 決議方法
1.基本語法
| 運算式 | 說明 |
|---|---|
| / | 從根節點選取 |
| // | 從檔案中選擇匹配當前節點的節點,而不考慮它們的位置 |
| nodename | 選取此節點的所有子節點 |
| . | 選取當前節點 |
| 兩點 | 選取當前節點的父親節點 |
| @ | 選取屬性 |
| * | 通配符,選取所有元素節點與元素名 |
| @* | 選取所有屬性 |
| [@attrib] | 選取具有指定屬性的所有元素 |
| [@attrib=‘value’] | 選取指定屬性具有匹配值的所有元素 |
| [tag] | 選取具有指定元素的直接子節點 |
| [tag=‘text’] | 選取具有指定元素并且文本內容是text的節點 |
例:
| 運算式 | 說明 |
|---|---|
| /bookstore/book[1] | 屬于 bokstore 子元素的第一個 book 元素 |
| /bookstore/book[position()<4] | 選取最前面 3 個屬于 bokstore 子元素的 book 元素 |
| //title[@lang = ‘eng’] | 選取所有 title 元素,并且這些元素擁有值為 eng 的 lang 屬性 |
2.基本操作
-匯入lxml: from lxml import etree
-生成XPath的決議物件:
html = etree.HTML(text) #呼叫HTML()生成決議物件,text型別為字串型別
html = etree.parse(text.xml) #呼叫parse()決議xml檔案
-決議物件輸出代碼 result = etree.tostring(html,encoding = 'utf-8')(了解)
-決議result = html.xpath(‘XPath運算式’)
XPath回傳的是 串列 型別
例:
1.獲取所有 tr 標簽:
trs = html.xpath("//tr")
for tr in trs:
print(etree.tostring(tr,encoding = 'utf-8').decode("utf-8"))
2.獲取第二個 tr 標簽:
trs = html.xpath("//tr[2]")
3.獲取所有 class = even 的標簽:
trs = html.xpath("//tr[@class='even']")
4.在當前標簽下:
href = tr.xpath(".//a") #一定要加. 不然//a默認在全域尋找,忽視 tr 標簽限制
BeautifulSoup庫 的用法
1 . 使用 lxml 決議將物件result 轉換成 BeautifulSoup 物件:
soup = BeautifulSoup(result, 'lxml')
2 .strings:如果tag中包含多個字串 ,可以使用 .strings 來回圈獲取
3 .stripped_strings:輸出的字串中可能包含了很多空格或空行,使用 .stripped_strings 可以去除多余空白內容
實體:
1.獲取所有 tr 標簽:
trs = soup.fid_all( ' tr ' )
2.獲取第2個標簽:
trs = soup.fid_all( ' tr ' ,limit = 2)[1]
3.獲取所有 class 為 even 的標簽:
方法一:trs = soup.fid_all( ' tr ',class_ = ' even ' )class一定要加_
方法二:trs = soup.fid_all( ' tr ',attrs = {' class ' : "even"} )
4.將所有 id = test, class = test 的 a 標簽提取出來:
方法一:aList = soup.fid_all( ' a ' , id = ' test ',class = ' test ')
方法二:aList = soup.fid_all( ' a ' , attrs = {' id' : " test " , ' class ' : "test"})
5.獲取所有a標簽的 href 屬性:
推薦方法一:通過下標
aList = soup.find_all('a')
for a in aList:
href = a['href']
方法二:通過attrs屬性回傳
aList = soup.find_all('a')
for a in aList:
href = a.attrs['href']
6.獲取所有職位資訊:
方法一:需要一個一個用下標檢索
trs = soup,find_all('tr')[1:]
for tr in trs:
tds=tr.find_all("td") #網頁上職位資訊是從第二個tr標簽開始,所以[1 : ]
title = tds[0].string #string:回傳字串
category= tds[1].string
推薦方法二:運用 .stripped_strings 來獲取 tr 標簽下所有 非標簽性、非空白 的字串(.strings與之相似,.strings 不會去掉空白字串)
trs = soup,find_all('tr')[1:]
for tr in trs:
infos = list(tr.stripped_strings) #.stripped_strings回傳的是一個生成器,需要list進行轉換成串列形式
或
infos = list(tr.get_text) #.get_text回傳的是字串型別
re正則運算式 的用法
正則運算式對 str 物件進行操作,在使用之前需要進行型別轉換,
通過requests.get() 請求
回傳型別是 requests.models.Response
實體:
resp = requests.get(base_url, headers=headers)
通過 text = resp.text 進行型別轉換,轉換成正則運算式對應的 str 型別
1.正則運算式的語法
點(.):匹配任意的字符(除了’\n’)
使用DOTALL標志,就可以讓 點(.) 匹配所有字符,不再排除換行符
[]組合的方式,只要滿足中括號中的某一項
\d \D:匹配任意的數字 非數字
\s:匹配的是空白字符(包括:\n,\t,\r和 空格)
\S:非空白字符
\w:匹配的是a-z和A-Z以及數字和下劃線
\W:匹配的是和\w相反的
*:匹配0個或者多個字符
例:re.match('\d\*',text) 匹配0個多個數字,任意個
+:匹配1個或者多個字符
例:re.match('\d\+',text) 匹配1個多個數字,至少有一個
?:匹配前一個字符0個或者1個
例:re.match('\d\?',text) 匹配0個或者1個數字
{m}:匹配m個字符
{m,n}:匹配m-n之間的個數的字符
^:匹配字串開頭
$:匹配字串結尾
\A \Z:指定的字串必須在開頭 結尾
貪婪模式:
例:
.+ 匹配一個或多個任意字符
text = "<h1>標題<h1>"
ret = re.match('<.+>',text)
回傳:<h1>標題<h1>
非貪婪模式:匹配最少
例:
text = "<h1>標題<h1>"
ret = re.match('<.+?>',text)
回傳:<h1> #非貪婪模式匹配滿足條件最短的
函式
1.match()從開頭匹配
2.search()任意匹配
3.group()
在寫正則運算式時候運用()括起來表示分組
group(1)表示第一個括號匹配的內容,以此類推
group(0)=group()是整個正則運算式的內容
group(1,2)第1-2個括號的內容
另:groups()拿出所有分組,除去group(0)
4.findall()回傳串列型別,找出所有滿足條件的結果
5.sub()替換字串
re.sub(‘正則運算式’,“0”)將滿足條件的替換成0
6.split()分割函式
re.split(‘正則運算式’,text)以滿足正則運算式的內容為界限分割
實戰
笑話網爬取
from urllib import request
def get_information():
for i in range(5782, 5788):
url = 'https://www.biedoul.com/index/i/'
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
}
rq = request.Request(url, headers=header)
resp = request.urlopen(rq)
print(resp.read().decode('utf-8'))
def main():
get_information()
if __name__ == '__main__':
main()
房源爬取
import requests
import re
def get_information():
base_url = "http://suqian.ganji.com/zufang/pn1/"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
resp = requests.get(base_url, headers=headers)
text = resp.text
houses = re.findall(r"""
<div.+?ershoufang-list.+?<a.+?js-title.+?>(.+?)</a> #獲取房源標題
.+?<dd.+?dd-item.+?size.+?<span>(.+?)</span> #戶型
.+?<div.+?price.+?<span.+?>(.+?)</span>#價格
""", text, re.VERBOSE | re.DOTALL) # re.VERBOSE 表示可以多行寫正則運算式并且加注釋
for house in houses:
print(house)
def main():
get_information()
if __name__ == '__main__':
main()
BaiduTranslate爬取
from urllib import request
from urllib import parse
import json
def get_information():
data = {'kw': '中國'}
dataurl = parse.urlencode(data)
url = 'https://fanyi.baidu.com/sug'
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
req = request.Request(url=url, data=dataurl.encode('utf-8'), headers=header)
response = request.urlopen(req).read()
ret = json.loads(response)
translate = ret['data'][0]['v']
print(translate)
def main():
get_information()
if __name__ == '__main__':
main()
top250爬取
from bs4 import BeautifulSoup
import requests
#import time
#time.sleep(5)
def get_detail_urls(detail_urls): # 1.獲取詳情頁面url
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
}
url = 'https://movie.douban.com/top250'
resp = requests.get(url, headers=headers)
html = resp.text
soup = BeautifulSoup(html, 'lxml')
lis = soup.find('ol', class_='grid_view').find_all('li')
for li in lis:
detail_url = li.find('a')['href']
detail_urls.append(detail_url) #detail_urls是所有url的串列集合
def get_detail_information(detail_urls): # 2.決議詳情頁面內容
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
}
for detail_url in detail_urls:
resp = requests.get(detail_url, headers=headers)
html = resp.text
soup = BeautifulSoup(html, 'lxml')
name = list(soup.find('div', id='content').find('h1').stripped_strings) # 電影名
name = ''.join(name)
print(name)
screenwriter = list(soup.find('div', id='info').find_all('span')[3].find('span', class_='attrs').stripped_strings)
print(screenwriter) # 編劇
print('-'*50)
def main():
detail_urls = []
get_detail_urls(detail_urls)
get_detail_information(detail_urls)
if __name__ == '__main__':
main()
瓜子二手車爬取(了解)
import requests
from lxml import etree
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',
'Cookie': ''
}
#獲取詳情頁面url
url = 'https://www.guazi.com/suqian/buy/'
resp = requests.get(url, headers=headers)
text = resp.content.decode('utf-8')
html = etree.HTML(text)
ul = html.xpath('//ul[@class="carlist clearfix js-top"]')[0]
# print(ul)
lis = ul.xpath('./li')
# print(lis)
for li in lis:
# print(lis)
detail_url = li.xpath('./a/@href')
# print(detail_url)
detail_url = 'https://www.guazi.com' + detail_url[0]
print(detail_url)
變成函式形式
def get_detail_urls(url):
resp = requests.get(url, headers=headers)
text = resp.content.decode('utf-8')
html = etree.HTML(text)
ul = html.xpath('//ul[@class="carlist clearfix js-top"]')[0]
# print(ul)
lis = ul.xpath('./li')
detail_urls = []
for li in lis:
detail_url = li.xpath('./a/@href')
detail_url = 'https://www.guazi.com' + detail_url[0]
# print(detail_url)
detail_urls.append(detail_url)
return detail_urls
#決議詳情頁面內容
for detail_urls in detail_urls:
resp = requests.get(detail_urls,headers = headers)
text = resp.content.decode('utf-8')
html = etree.HTML(text)
title = html.xpath('//div[@class="product-textbox"]/h2/text()')[0]
title = title.replace(r'\r\n','').strip()
print(title)
info = html.xpath('//div[@class="product-textbox"]/ul/li/span/text()')
print(info)
infos = {}
cardtime = info[0]
km = info[1]
displacement = info[2]
speedbox = info[3]
infos['title'] = title
infos['cardtime'] = cardtime
infos['km'] = km
infos['displacement'] = displacement
infos['speedbox'] = speedbox
return infos
#保存資料
def save_data(infos,f):
f.write('{},{},{},{},{}\n'.format(infos['title'],infos['cardtime'],infos['km'],infos['displacement'],infos['speedbox']))
def main():
#第一個url
base_url = 'https://www.guazi.com/suqian/buy/'
with open('guazi_cs.csv', 'a', encoding='utf-8') as f:
url = base_url.format(x)
#獲取詳情頁面url
detail_urls = get_detail_urls(url)
#決議詳情頁面內容
for detail_url in detail_urls:
infos = parse_detail_page(detail_url)
save_data(infos,f)
if __name__ == '__main__':
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/237649.html
標籤:python
上一篇:理想國Python入門教程
下一篇:python學習總結part1
