整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

四种解决Nginx出现403 forbidden 报错的方法

是在在本地用虚拟机中通过yum安装nginx的,安装一切正常,但是访问时报403,

于是查看nginx日志,路径为/var/log/nginx/error.log。打开日志发现报错Permission denied,详细报错如下:

1. open() "/data/www/1.txt" failed (13: Permission denied), client: 192.168.1.194, server: www.web1.com, request: "GET /1.txt HTTP/1.1", host: "www.web1.com"

没有权限?于是找了不少资料,可以通过下面四步排查解决此问题。你可能只是其中之前配置有问题,不一定四个步骤都用上。

一、由于启动用户和nginx工作用户不一致所致

1.1查看nginx的启动用户,发现是nobody,而为是用root启动的

命令:ps aux | grep "nginx: worker process" | awk'{print }'

1.2将nginx.config的user改为和启动用户一致,

命令:vi conf/nginx.conf

二、缺少index.html或者index.php文件,就是配置文件中index index.html index.htm这行中的指定的文件。

1. server {2. listen 80;3. server_name localhost;4. index index.php index.html;5. root /data/www/;6. }

如果在/data/www/下面没有index.php,index.html的时候,直接文件,会报403 forbidden。

三、权限问题,如果nginx没有web目录的操作权限,也会出现403错误。

解决办法:修改web目录的读写权限,或者是把nginx的启动用户改成目录的所属用户,重启Nginx即可解决

1. chmod -R 777 /data2. chmod -R 777 /data/www/

四、SELinux设置为开启状态(enabled)的原因。

4.1、查看当前selinux的状态。

1. /usr/sbin/sestatus

4.2、将SELINUX=enforcing 修改为 SELINUX=disabled 状态。

1. vi /etc/selinux/config2.3. #SELINUX=enforcing4. SELINUX=disabled

4.3、重启生效。reboot。

1. reboot

ginx不仅仅只是一款反向代理和负载均衡服务器,它还能提供很多强大的功能,例如:限流、缓存、黑白名单和灰度发布等等。在之前的文章中,我们已经介绍了Nginx提供的这些功能。今天,我们来介绍Nginx另一个强大的功能:禁用IP和IP段。

禁用IP和IP段

Nginx的ngx_http_access_module 模块可以封配置内的ip或者ip段,语法如下:

deny IP; 
deny subnet; 
allow IP; 
allow subnet; 
# block all ips 
deny    all; 
# allow all ips 
allow    all; 

如果规则之间有冲突,会以最前面匹配的规则为准。

配置禁用ip和ip段

下面说明假定nginx的目录在/usr/local/nginx/。

首先要建一个封ip的配置文件blockips.conf,然后vi blockips.conf编辑此文件,在文件中输入要封的ip。

deny 1.2.3.4;
deny 91.212.45.0/24; 
deny 91.212.65.0/24; 

然后保存此文件,并且打开nginx.conf文件,在http配置节内添加下面一行配置:

include blockips.conf; 

保存nginx.conf文件,然后测试现在的nginx配置文件是否是合法的:

/usr/local/nginx/sbin/nginx -t 

如果配置没有问题,就会输出:

the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful 

如果配置有问题就需要检查下哪儿有语法问题,如果没有问题,需要执行下面命令,让nginx重新载入配置文件。

/usr/local/nginx/sbin/nginx -s reload 

仅允许内网ip

如何禁止所有外网ip,仅允许内网ip呢?

如下配置文件

location / { 
  # block one workstation 
  deny    192.168.1.1; 
  # allow anyone in 192.168.1.0/24 
  allow   192.168.1.0/24; 
  # drop rest of the world 
  deny    all; 
} 

上面配置中禁止了192.168.1.1,允许其他内网网段,然后deny all禁止其他所有ip。

格式化nginx的403页面

如何格式化nginx的403页面呢?

首先执行下面的命令:

cd /usr/local/nginx/html
vi error403.html 

然后输入403的文件内容,例如:

<html> 
<head><title>Error 403 - IP Address Blocked</title></head> 
<body> 
Your IP Address is blocked. If you this an error, please contact binghe with your IP at test@binghe.com 
</body> 
</html> 

如果启用了SSI,可以在403中显示被封的客户端ip,如下:

Your IP Address is <!--#echo var="REMOTE_ADDR" --> blocked. 

保存error403文件,然后打开nginx的配置文件vi nginx.conf,在server配置节内添加下面内容。

# redirect server error pages to the static page 
 error_page   403  /error403.html; 
 location = /error403.html { 
         root   html; 
 } 

然后保存配置文件,通过nginx -t命令测试配置文件是否正确,若正确通过nginx -s reload载入配置。


HTMLAgilityPack 是一个开源的.NET库,旨在帮助开发人员处理和操作HTML文档。它提供了解析HTML文档、查询DOM元素以及修改HTML内容的功能。HTMLAgilityPack 基于XPath和LINQ查询,使得开发者能够以类似于操作XML文档的方式来操作HTML文档。这使得从复杂的HTML结构中提取所需数据变得轻而易举。

正文


HTMLAgilityPack 主要用于以下几个方面:

  1. 解析HTML文档:HTMLAgilityPack 可以将原始的HTML文档解析成一个DOM(文档对象模型)树,使开发者能够轻松地遍历和操作HTML元素。
  2. 查询和选择元素:通过使用XPath表达式或LINQ查询,您可以轻松地选择和定位HTML文档中的特定元素,从而实现数据的抽取和操作。
  3. 修改HTML内容:您可以使用HTMLAgilityPack来添加、删除或修改HTML元素和属性,以满足特定的需求。
  4. HTML格式化与转换:HTMLAgilityPack 还允许您将HTML文档格式化为漂亮的字符串或转换为其他格式,如纯文本或Markdown。

常用方法与学用属性

以下是一些常用的HTMLAgilityPack方法和属性,以及它们的用途:

  1. HtmlDocument.Load(string path):从指定路径加载HTML文档。
  2. HtmlDocument.LoadHtml(string html):从字符串加载HTML文档。
  3. HtmlDocument.DocumentNode:获取整个HTML文档的根节点。
  4. SelectSingleNode(string xpath):根据XPath表达式选择单个节点。
  5. SelectNodes(string xpath):根据XPath表达式选择多个节点。
  6. InnerText:获取或设置元素的文本内容。
  7. OuterHtml:获取或设置元素及其内部内容的HTML。
  8. Attributes:获取元素的属性集合。
  9. AppendChild(HtmlNode newChild):将新节点添加为子节点。
  10. Remove():从文档中移除当前节点。

Nuget安装 HtmlAgilityPack库

解析并显示标题

我们使用 HttpClient 发送一个 GET 请求到指定的 HTTPS URL,并且读取返回的响应内容。

如果出现 HTTP 状态码 403 (Forbidden) 错误表示您的请求被服务器拒绝,通常是因为服务器认为您没有权限访问该资源。

  1. 检查网站访问权限:确保您有权访问目标网站。有些网站可能需要登录或具有特定权限才能访问其内容。
  2. 用户代理头:有些网站要求用户代理标头,您可以尝试在请求中添加一个用户代理标头来模拟浏览器行为
  3. Cookies 和 Session:如果目标网站使用 cookies 或会话来管理访问权限,请确保您正确处理这些信息。您可能需要发送适当的 cookies 或会话信息以获取访问权限。
  4. IP封锁:某些网站可能根据 IP 地址阻止访问,如果您的 IP 被封锁,您可能需要使用代理服务器来绕过封锁。
  5. 代理服务器:如果您的网络中存在代理服务器,请确保代理服务器的设置正确,并且允许访问目标网站。
  6. 身份验证:如果网站需要身份验证,您可能需要在请求中包含适当的身份验证凭据。您可以使用 HttpClient 的 DefaultRequestHeaders.Authorization 属性来添加身份验证标头。
  7. 请求头和参数:某些网站可能会要求特定的请求头或查询参数,您需要查看网站的文档或分析网络请求以确定所需的请求标头和参数。
private async void btnGetTitle_Click(object sender, EventArgs e)
{
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();

    string htmlContent = "";
    using (HttpClient httpClient = new HttpClient())
    {
        try
        {

            httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3");
           
            HttpResponseMessage response = await httpClient.GetAsync("https://www.baidu.com");
            
            //检查 HTTP 响应的状态码是否表示成功
            response.EnsureSuccessStatusCode();

            //读取内容
            byte[] bytes = await response.Content.ReadAsByteArrayAsync();
            htmlContent = Encoding.UTF8.GetString(bytes);

        }
        catch (HttpRequestException ex)
        {

        }
    }

    doc.LoadHtml(htmlContent);

    HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//title");
    if (titleNode != null)
    {
        string title = titleNode.InnerText;
        MessageBox.Show($"页面标题:{title}");
    }
}

提取所有链接

/// <summary>
/// 通过url取得html内容
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private async Task<string> GetHtml(string url)
{

    string htmlContent = "";
    using (HttpClient httpClient = new HttpClient())
    {
        try
        {

            httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3");

            HttpResponseMessage response = await httpClient.GetAsync(url);

            response.EnsureSuccessStatusCode();

            //读取内容
            byte[] bytes = await response.Content.ReadAsByteArrayAsync();
            htmlContent = Encoding.UTF8.GetString(bytes);

        }
        catch (HttpRequestException ex)
        {

        }
    }
    return htmlContent;
}

private async void btnGetLinks_Click(object sender, EventArgs e)
{
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    string htmlContent =await GetHtml("https://www.baidu.com");
    doc.LoadHtml(htmlContent);

    HtmlNodeCollection linkNodes = doc.DocumentNode.SelectNodes("//a[@href]");
    if (linkNodes != null)
    {
        foreach (HtmlNode linkNode in linkNodes)
        {
            string link = linkNode.GetAttributeValue("href", "");
            lstLink.Items.Add(link);
        }
    }
}

通过class 去找节点

private async void btnGetSpecialLink_Click(object sender, EventArgs e)
{
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    string htmlContent = await GetHtml("https://news.baidu.com/");
    doc.LoadHtml(htmlContent);

    HtmlNodeCollection linkNodes = doc.DocumentNode.SelectNodes("//*[@id=\"pane-news\"]/ul/li[@class=\"bold-item\"]/a");
    if (linkNodes != null)
    {
        foreach (HtmlNode linkNode in linkNodes)
        {
            string link = linkNode.GetAttributeValue("href", "");
            string title = linkNode.InnerText;
            lnkSpecialLink.Items.Add(title + " " + link);
        }
    }
}

快速找到节点path

Linq 找查节点