91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何實現Python進階多線程爬取網頁項目

發布時間:2021-10-21 17:14:06 來源:億速云 閱讀:177 作者:iii 欄目:開發技術

這篇文章主要介紹“如何實現Python進階多線程爬取網頁項目”,在日常操作中,相信很多人在如何實現Python進階多線程爬取網頁項目問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何實現Python進階多線程爬取網頁項目”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

目錄
  • 一、網頁分析

  • 二、代碼實現

一、網頁分析

這次我們選擇爬取的網站是水木社區的Python頁面
網頁:https://www.mysmth.net/nForum/#!board/Python?p=1

如何實現Python進階多線程爬取網頁項目

根據慣例,我們第一步還是分析一下頁面結構和翻頁時的請求。

如何實現Python進階多線程爬取網頁項目

如何實現Python進階多線程爬取網頁項目

如何實現Python進階多線程爬取網頁項目

通過前三頁的鏈接分析后得知,每一頁鏈接中最后的參數是頁數,我們修改它即可得到其他頁面的數據。

再來分析一下,我們需要獲取帖子的鏈接就在id 為 body 的 section下,然后一層一層找到里面的 table,我們就能遍歷這些鏈接的標題。

如何實現Python進階多線程爬取網頁項目

我們點開一篇帖子:https://www.mysmth.net/nForum/#!article/Python/162717

和前面一樣,我們先分析標題和內容在網頁中的結構

不難發現,主題部分只要找到id 為 main 的 section 下面的 class 為 b-head corner 的下面第二個 span即可
主題部分

如何實現Python進階多線程爬取網頁項目

而內容部分只要找到class 為 a-wrap corner 的 div,找到下面的 a-content即可。
內容部分

如何實現Python進階多線程爬取網頁項目

分析網頁結構后,我們就可以開始寫代碼了!

二、代碼實現

首先要確定要保存什么內容:這次我們保存水木社區 Python 版面前 10 頁的所有帖子標題和帖子第一頁的所有回復。

解析列表頁,得到所有的帖子鏈接

from bs4 import BeautifulSoup
# 解析列表頁內容,得到這一頁的內容鏈接
def parse_list_page(text):
  soup = BeautifulSoup(text, 'html.parser')
	# 下面相當于 soup.find('table', class_='board-list tiz').find('tbody')
  tbody = soup.find('table', class_='board-list tiz').tbody
  urls = []
  for tr in tbody:
    td = tr.find('td', class_='title_9')
    urls.append(td.a.attrs['href'])
  return urls

解析內容頁,得到標題和這一頁的所有帖子內容

# 解析內容頁,得到標題和所有帖子內容
def parse_content_page(text):
  soup = BeautifulSoup(text, 'html.parser')
  title = soup.find('span', class_='n-left').text.strip('文章主題:').strip()
  content_div = soup.find('div', class_='b-content corner')
  contents = []
  for awrap in content_div.find_all('div', class_='a-wrap corner'):
    content = awrap.p.text
    contents.append(content)
  return title, contents

把列表頁的鏈接轉換成我們要抓取的鏈接

def convert_content_url(path):
  URL_PREFIX = 'http://www.mysmth.net'
  path += '?ajax'
  return URL_PREFIX + path

生成前 10 頁的列表頁鏈接

list_urls = []
for i in range(1, 11):
  url = 'http://www.mysmth.net/nForum/board/Python?ajax&p='
  url += str(i)
  list_urls.append(url)

下面是得到前 10 頁列表頁里所有正文的鏈接。這個時候我們使用線程池的方式來運行

import requests
from concurrent import futures
session = requests.Session()
executor = futures.ThreadPoolExecutor(max_workers=5)
# 這個函數獲取列表頁數據,解析出鏈接,并轉換成真實鏈接
def get_content_urls(list_url):
  res = session.get(list_url)
  content_urls = parse_list_page(res.text)
  real_content_urls = []
  for url in content_urls:
    url = convert_content_url(url)
    real_content_urls.append(url)
  return real_content_urls
# 根據剛剛生成的十個列表頁鏈接,開始提交任務
fs = []
for list_url in list_urls:
  fs.append(executor.submit(get_content_urls, list_url))
futures.wait(fs)
content_urls = set()
for f in fs:
  for url in f.result():
    content_urls.add(url)

在這里要注意一下,第 23 行中我們使用了 set() 函數,作用是去除重復值。它的原理是創建一個 Set(集合),集合 是 Python 中的一種特殊數據類型,其中可以包含多個元素,但是不能重復。我們來看看 set() 的用法

numbers = [1, 1, 2, 2, 2, 3, 4]
unique = set(numbers)
print(type(unique))
# 輸出:<class 'set'>
print(unique)
# 輸出:{1, 2, 3, 4}

我們看到,set() 將列表 numbers 轉換成了沒有重復元素的集合 {1, 2, 3, 4}。

我們利用這個特性,首先在 23 行通過 content_urls = set() 創建了一個空集合,之后在其中添加鏈接時,就會自動去除多次出現的鏈接。

得到了所有正文鏈接之后,我們解析正文頁內容,放到一個字典里

# 獲取正文頁內容,解析出標題和帖子
def get_content(url):
  r = session.get(url)
  title, contents = parse_content_page(r.text)
  return title, contents
# 提交解析正文的任務
fs = []
for url in content_urls:
  fs.append(executor.submit(get_content, url))
futures.wait(fs)
results = {}
for f in fs:
  title, contents = f.result()
  results[title] = contents
print(results.keys())

就這樣,我們完成了多線程的水木社區爬蟲。打印 results.keys() 可以看到所有帖子的標題。

這次爬取了前十頁的所有主題,以及他們的第一頁回復。一共 10 個列表頁、300 個主題頁,解析出 1533 條回復。在一臺網絡良好、性能普通的機器上測試執行只花費了 13 秒左右。

完整代碼如下

import requests
from concurrent import futures
from bs4 import BeautifulSoup
# 解析列表頁內容,得到這一頁的內容鏈接
def parse_list_page(text):
  soup = BeautifulSoup(text, 'html.parser')
  tbody = soup.find('table', class_='board-list tiz').tbody
  urls = []
  for tr in tbody:
    td = tr.find('td', class_='title_9')
    urls.append(td.a.attrs['href'])
  return urls
# 解析內容頁,得到標題和所有帖子內容
def parse_content_page(text):
  soup = BeautifulSoup(text, 'html.parser')
  title = soup.find('span', class_='n-left').text.strip('文章主題:').strip()
  content_div = soup.find('div', class_='b-content corner')
  contents = []
  for awrap in content_div.find_all('div', class_='a-wrap corner'):
    content = awrap.p.text
    contents.append(content)
  return title, contents
# 把列表頁得到的鏈接轉換成我們要抓取的鏈接
def convert_content_url(path):
  URL_PREFIX = 'http://www.mysmth.net'
  path += '?ajax'
  return URL_PREFIX + path
# 生成前十頁的鏈接
list_urls = []
for i in range(1, 11):
  url = 'http://www.mysmth.net/nForum/board/Python?ajax&p='
  url += str(i)
  list_urls.append(url)
session = requests.Session()
executor = futures.ThreadPoolExecutor(max_workers=5)
# 這個函數獲取列表頁數據,解析出鏈接,并轉換成真實鏈接
def get_content_urls(list_url):
  res = session.get(list_url)
  content_urls = parse_list_page(res.text)
  real_content_urls = []
  for url in content_urls:
    url = convert_content_url(url)
    real_content_urls.append(url)
  return real_content_urls
# 根據剛剛生成的十個列表頁鏈接,開始提交任務
fs = []
for list_url in list_urls:
  fs.append(executor.submit(get_content_urls, list_url))
futures.wait(fs)
content_urls = set()
for f in fs:
  for url in f.result():
    content_urls.add(url)
# 獲取正文頁內容,解析出標題和帖子
def get_content(url):
  r = session.get(url)
  title, contents = parse_content_page(r.text)
  return title, contents
# 提交解析正文的任務
fs = []
for url in content_urls:
  fs.append(executor.submit(get_content, url))
futures.wait(fs)
results = {}
for f in fs:
  title, contents = f.result()
  results[title] = contents
print(results.keys())

到此,關于“如何實現Python進階多線程爬取網頁項目”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

云南省| 江口县| 泸定县| 新民市| 禹州市| 金沙县| 阳谷县| 铁岭市| 武强县| 宣威市| 宣恩县| 桦甸市| 洛浦县| 资源县| 通城县| 通化市| 镇坪县| 汨罗市| 科尔| 邳州市| 叶城县| 宁城县| 富裕县| 东莞市| 墨玉县| 玛沁县| 延川县| 黔江区| 新安县| 宿迁市| 临汾市| 策勒县| 张家界市| 九台市| 通城县| 全椒县| 湟中县| 无棣县| 定边县| 平阴县| 南木林县|