php正则函数抓取网页连接(爬虫实现第一步,提取一个页面里的所有http连接1.获得网页源码)
优采云 发布时间: 2021-10-09 06:18php正则函数抓取网页连接(爬虫实现第一步,提取一个页面里的所有http连接1.获得网页源码)
爬虫的目标网站是/,我想抓取这个网站中的每篇文章文章,并且必须获取网站 url中每一页的信息,具体思路如下面所述:
进入网站的首页,使用正则表达式提取所有以/开头的网址,将第一步提取的网址一一抓取,在新网页中提取所有符合要求的网址
如果你有数据结构的基础,你一定已经了解了门道。从一个 url 到一个页面,这个页面中还会有其他的 http 连接。输入其中一个连接后,您可以获得新的 http 链接,它们形成一棵树。我的程序可以选择广度优先遍历或深度优先遍历,但是无论哪种遍历方式,我都需要提取一个页面中的所有http链接。
访问过的url可以放入一个集合中。在访问新的 url 之前,请检查该 url 是否已被访问过。对于单个网站,url的数量不会太多,数以万计。,使用采集来保存它们。
思路已经有了,我们来实现第一步,提取一个页面中的所有http连接
1. 获取网页源码
首先实现一个获取指定url的html源码的函数
import requests
def get_html(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',
}
res = requests.get(url, headers=headers)
return res.text
我实现的这个功能很简单,没有考虑请求超时和http代理,我们很快就实现了这个功能,然后遇到问题就解决了。
2. 提取网页中的所有网址
def extract_all_urls(html):
pattren = re.compile(r'https://www.lz13.cn/[^\s]+.html')
url_lst = pattren.findall(html)
return url_lst
正则表达式匹配以 / 开头并以 .html 结尾的文本,因此设计表达式基于两个考虑
只提取本站内的链接,其他如友情链接不考虑只提取html页面,其他如js、css不需要提取3.所有站点提取
def get_urls_from_url(url):
html = get_html(url)
url_lst = extract_all_urls(html)
return url_lst
首先实现get_urls_from_url,负责向一个url发起请求,调用extract_all_urls获取这个url中的所有链接。
接下来实现提取全站url的功能
import requests
import re
import time
from collections import deque
def get_html(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',
}
res = requests.get(url, headers=headers)
return res.text
def extract_all_urls(html):
pattren = re.compile(r'https://www.lz13.cn/[^\s]+.html')
url_lst = pattren.findall(html)
return url_lst
def get_urls_from_url(url):
html = get_html(url)
url_lst = extract_all_urls(html)
return url_lst
def get_all_urls(web_site):
url_access_set = set() # 已经访问过的url
queue_url_set = set()
url_lst = get_urls_from_url(web_site)
url_access_set.add(web_site)
queue = deque()
for url in url_lst:
queue.append(url)
queue_url_set.add(url)
while len(queue) != 0:
print(len(queue))
url = queue.popleft()
if url in url_access_set:
continue
url_access_set.add(url)
url_lst = get_urls_from_url(url)
for url in url_lst:
if url not in queue_url_set:
queue.append(url)
queue_url_set.add(url)
return url_access_set
if __name__ == '__main__':
all_urls = get_all_urls('https://www.lz13.cn')
print(len(all_urls))
get_all_urls 函数实现了广度优先遍历。本来以为这个网站的url不是很多,但是跑了一会,队列里的url越来越多。看来单线程运行是不现实的。我知道什么时候必须运行以遍历整个 网站 url。在下面的文章中,我将对该程序进行改造以加快爬行速度。