21
2025
03
16:48:42

部署SearXNG并且把集成搜狗微信这件事

一、什么是SearXNG

SearXNG 是一个免费的互联网元搜索引擎,它来自各种搜索服务和数据库的结果。用户既不被跟踪,也不会被分析。

其中NG意味next generation,表示下一代,听说是项目组内部对SearX未来发展意见不合而产生的分支

简单来说,SearXNG是一个同时集成了Google、Yahoo、Bilibili甚至Pivix等各式各样的搜索引擎的搜索引擎(哈哈),并且不会被收集用户数据,以达到阻止个性化推荐这样的服务。如果你是一个注重隐私保护的用户,用用searxng也是不错的。

部署SearXNG并且把集成搜狗微信这件事

二、如何将SearXNG部署到自己的电脑上

作为一个不知道什么职位的什么都不会的小白,其实一开始拿到这个任务我是懵逼的。

什么是部署?怎么部署?给了我一个github链接我却连看都看不懂怎么办?

1.看懂SearXNG源

GItHub链接

一般来说,看懂一个github项目,首先看Readme(读我)

部署SearXNG并且把集成搜狗微信这件事

它的readme写的很简略,是因为它其实有一个专门的“说明书”,点击“homepage”就能跳转

部署SearXNG并且把集成搜狗微信这件事

我花了很长时间才搞清楚这份说明书的“架构”,最终锁定在“step by step installation”这一栏,里面详尽地说明了如何在本地部署自己的SearXNG,虽然是纯英文的

2.部署环境的准备

话又说回什么是部署了,到底什么是部署?我以为,部署就是把这个项目的源下载到你的电脑(或者说本地)上,以便于你自己开发调试,增加或减少自己想要的功能。例如我就需要在它集成了这么多搜索引擎的基础上,再集成一个搜狗微信的引擎。相当于,你在别人的源代码的基础上,开发出了一个个性化的属于你自己的SearXNG.可能这就是开源项目的魅力吧。

SearXNG是基于docker环境或者python环境开发的,但我不太懂什么是docker,而且貌似我的系统装不了docker?就选择基于python环境开发。(说实话我也不是很懂什么叫基于某某环境?)

(1)Anaconda

Anaconda介绍

以前不理解Anaconda的用处在哪里,想着写python用pycharm不就行了吗?

没错,在学校读书只会用pycharm写代码是这样的,我们做项目的考虑可就多了。

一个项目的部署或者叫运行,需要特定的环境,这个环境包括python的版本,以及这种包的版本。不同的项目需要的版本是不同,这Anaconda的作用就在于可以便捷的获取包,以及方便的管理不同的环境,而这些在pycharm实现起来则相对复杂。

Anaconda的下载相信大家都没问题,这里贴上我写的Anaconda的基本使用语句的blog

Anaconda虚拟环境的配置

Anaconda虚拟环境配置

那么,我们究竟要配置什么样的环境呢?这时候我们就要深入项目文件中一探究竟。
部署SearXNG并且把集成搜狗微信这件事
首先我们在"setup.py"文件中看到这么一句话“python_requires='>=3.8'”
也就是说我们需要3.8版本以上的python解释器

conda create --name searxng python=3.9

这里我们创建了一个叫“searxng”的版本为3.9的环境
接下来,我们观察它的项目文件中,有一个叫“requirements.txt”的文件,一般来说,一个项目的“依赖”,也就是它运行所需要的包的目录都在这个文件里写着。那么我们怎么一次性把该文件里的包一次性安装好呢?

pip install -r "requirements.txt"

这条语句将文件里的包一次性全部安装好。
注意!!!在此之前,需要用cd命令进去requirements所在的文件夹(在此之前你需要将github上的项目下载到本地),否则conda是不知道这个文件在什么地方的。
这时候我们发现,诶?怎么报错了?
原因在于,UVLoop底层使用了Unix/Linux系统的API,因此目前无法在Windows系统上安装和使用!看来我使了个坏,白忙活了一场。

(2)虚拟机与Linux

windows系统上行不通,那我们就只能在linux系统上进行接下来的操作了,而linux系统(没有意外的话)则需要在虚拟机上构建。
教程我是看的阿b的视频-->VMware及ubuntu安装
全程无废话,这是真的。互联网真好,想学什么上网一搜就有。
ps:unbuntu(乌班图)可以理解成是linux的一个系统型号,就像win10、winX之于windows.


接下来,我们要

1.安装anaconda(尝试使用命令安装)
进入anaconda官网,找到这个界面
部署SearXNG并且把集成搜狗微信这件事
右键,选择复制链接。
这时候打开ubuntu,使用Ctrl+Alt+T打开终端
输入以下命令

wget https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh

等待下载完成后,再输入

bash ~/Downloads/Anaconda3-2024.06-1-Linux-x86_64.sh

注:该语句指定了安装路径“~/Downloads/"已经安装包名称“Anaconda3-2024.06-1-Linux-x86_64.sh”,有需要可以更改路径,注意包名称与wget命令保持一致

接下来,依照上文方法配置完环境(searxng)后,我们用git clone命令将项目安装在Ubuntu本地

(searxng)$ git clone "https://github.com/searxng/searxng" \
                   "/home/usr/searxng"

接下来,我们需要安装指定包。与上文大同小异,此处不再赘述。

值得注意的是,环境配置环境有很关键一步如下,尽管我还不知道它的作用是什么

(searxng)$ cd /home/usr/searxng
(searxng)$ pip install -e .

至此,环境配置相关基本完成。

3.虚拟机网络代理配置

首先,代理软件开启允许局域网连接

部署SearXNG并且把集成搜狗微信这件事

同时,记住我们的端口号7890


接下来,我们要找我们本地计算的ip

方法一

部署SearXNG并且把集成搜狗微信这件事

代理软件可能会自带有,这里的WLAN就是我们的ip地址

方法二

win+R,输入cmd,打开命令行窗口

C:\Users\Lenovo>ipconfig

部署SearXNG并且把集成搜狗微信这件事

可以看到我们的IPv4地址,与刚才是一致的


紧接着,我们配置虚拟机

部署SearXNG并且把集成搜狗微信这件事

这一步表示虚拟机的所有网络服务操作交给主机去执行


打开虚拟机,找到网络设置

部署SearXNG并且把集成搜狗微信这件事

将网络代理改为手动,将这三行ip改为刚才我们查询到的ip,端口号也记得更改

此时我们已经能使用google等网站了


最后,找到searxng-->searx-->settings.yml文件

部署SearXNG并且把集成搜狗微信这件事

找到proxies,默认是被注释掉的,我们取消注释,并添加我们刚才查询到的ip地址

yml文件对缩进很敏感,请一定注意

4.SearXNG?启动!

$ sudo -H mkdir -p "/etc/searxng"
$ sudo -H cp "/usr/local/searxng/settings.yml" \
             "/etc/searxng/settings.yml"

首先在虚拟机终端执行这两条语句,命令1在指定路径创建文件夹,命令2将配置文件复制到刚才创建的文件夹

$ sudo -H sed -i -e "s/debug : False/debug : True/g" "/etc/searxng/settings.yml"
(searxng)$ cd /usr/local/searxng/searx
(searxng)$ export SEARXNG_SETTINGS_PATH="/etc/searxng/settings.yml"
(searxng)$ python webapp.py

接着执行这四条语句,语句1打开调试模式,语句2进去指定路径,语句3引用环境变量,语句4运行app

这时候,如果没有报错,我们在虚拟机的浏览器上进入

http://127.0.0.1:8888

便成功启动SearXng了

三、如何集成微信搜索引擎到SearXNG

不出意外的话,终于要开始coding了

1.准备工作:使用VSCode远程调试虚拟机文件

详情见-->详细教学

//2024.11.02更新..鸽了这么久终于回坑了。。有很多细节的东西可能都忘了..只能大概的填坑了

糟糕,ssh: connect to host XXXX port 22: Connection refused

如果你像我一样遇见了这个报错,那么可以看看下面的视频

详情点击下方链接

SSH ERROR

如果你可以使用VScode远程调试,那么你会看到如下的界面:

部署SearXNG并且把集成搜狗微信这件事

当然,这个wechat.py就是我们将要编写的文件了

2.开始coding!

开始之前...

开始之前,我们需要仔细看看这个项目的架构。当然,这不是一件容易的事。对于接触项目不多的初学者来说,这简直是灾难...去网上搜资料也很少,又不好意思太去频繁地问负责人,最后之后把文件名字一个一个丢给gpt问..“这个文件是干什么的?”“那个文件是干什么的?”好在gpt也足够耐心,虽然他回答的细节可能有问题,但是整体架构还是没问题的。

部署SearXNG并且把集成搜狗微信这件事

在茫茫的文件夹和文件中,我们着重需要注意的是这两个。其中,requirements文件前面也说了,是需要的环境。那么这个searx,可以理解成我们这个搜索引擎的本体了


我们进去这个文件夹看看

部署SearXNG并且把集成搜狗微信这件事

同样的,需要我们着重注意的,一个是engines,里面存放了我们集成的搜索引擎,比如google;一个是settings,是配置文件;最后一个是webapp,是我们实现网页的方式。

简而言之,这三者的逻辑大概是,我们在engines里编写某个特定的engine,通过settings集成在一起,最后通过webapp展示。

编辑settings.yml

我们按照yml文件的格式,仿照其他引擎,编写我们wechat的配置

部署SearXNG并且把集成搜狗微信这件事

其中shortcut表示缩写,在我们搜索时会有用。

wechat.py的编写

我们观察到(我观察了google,yahoo和pivix..)一个引擎的py文件结构大概是

import//调包,主要是内部自己编写的包

about = {

}//配置,与setting对应


def request(query, params)://请求头
//query表示待搜索的关键字,params表示参数,如url,headers,cookies等
    return params//返回参数


def response(resp)://响应
//内部用类似xpath的方法解析寻找resp.text的内容
    return results//rusults中记录了搜索到的标题,内容等
难点解析
(1)about的编写

about是最好写的,因为只要仿照别的配置文件就没问题

我的about是这样写的,大家的差不多就行

about={
    "website": 'https://weixin.sogou.com/weixin',
    "wikidata_id": None,
    "official_api_documentation": None,
    "use_official_api": False,
    "require_api_key": False,
    "results": 'HTML',
}
categories = ['general', 'web']
paging = True
time_range_support = False

只要注意categories中'general'表示 常用,'web'表示引擎返回结果是网页,这些参照google的编写就没问题

(2)requests中params究竟有哪些参数?

部署SearXNG并且把集成搜狗微信这件事

关于这个问题,我们似乎能从一个叫online.py的文件的params的初始化中寻到答案

(至于我是怎么找到的,我只能说这是一个艰苦卓绝的过程..)

部署SearXNG并且把集成搜狗微信这件事

但最重要的是第116行的代码,超级无敌重要,因为有很多报错会错在这里。。

也就是说,params里最重要的还是url的构建

(3)XPath

在response方法中,我们需要用类似xpath的方式在爬取公众号的标题,内容等等,也就是说我们得先学xpath->xpath学习

如果学习好xpath,我们再对照着其他搜索引擎看看项目本身编写的类xpath方法是怎么用的,很相似就是了。

(4)搜狗微信的爬取

由于搜狗微信存在很强的反爬机制,我们在爬虫这块得多下点功夫了。

import re
import requests
# from bs4 import BeautifulSoup
from lxml import etree
from urllib.parse import quote
import random


# import time


# from lxml import etree

def url_decode(r):
    url = 'https://weixin.sogou.com' + r
    b = random.randint(0, 99)
    a = url.index('url=')
    a = url[a + 30 + b:a + 31 + b:]
    url += '&k=' + str(b) + '&h=' + a
    return url


usr_agents = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
    Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0',
    'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)\
     Chrome/83.0.4103.116 Safari/537.36'
]
cks = [
    'ABTEST=0|1722388018|v1; SUID=A2FECF7C1252A20B0000000066A98E32; \
    IPLOC=CN1100; SUID=A2FECF7C1AA7A20B0000000066A98E34; SUV=005224EA7CCFFEA266A99380942FF064; \
    ssuid=6905076304; PHPSESSID=laqcp42b40k82bcnplh7e47to1; SNUID=194273C0BCBDA49EE380D5D1BC347914; \
    ariaDefaultTheme=undefined',
    'ABTEST=7|1722413935|v1; SUID=A2FECF7C8E52A20B0000000066A9F36F; IPLOC=CN1100; \
    SUV=00364C407CCFFEA266A9F3708B596656; SUID=A2FECF7CC254A20B0000000066A9F31D; \
    SNUID=CD8EBF1370767184577E281070766C3A; ariaDefaultTheme=undefined'
]


def create_hdr():
    hdr = {
        'User-Agent': usr_agents[1],
        'Cookie': cks[0],
        'Referer': 'https://weixin.sogou.com/weixin?query=12306&type=2&page=1&ie=utf8'
    }
    return hdr


def crowler(keyword: str):
    kw_encoded = quote(keyword)
    proxy = {'http': '127.0.0.1:7890', 'https': '127.0.0.1:7890'}
    for page in range(1, 2):
        url = 'https://weixin.sogou.com/weixin?query={}&type=2&page={}'.format(kw_encoded, page)
        response = requests.get(url, headers=create_hdr(), proxies=proxy)
        urls = []
        if response.status_code >= 300:
            print(response.status_code)
        else:
            print(response.text)
            tree = etree.HTML(response.text)
            for ele in tree.xpath('//div[@class="txt-box"]/h3/a/@href'):
                href = url_decode(ele)
                urls.append(href)
                # print(ele)
            # 读取新得到的url
            # print(urls[0])
            if len(urls) == 0:
                print(response.url)
                # strr = tree.xpath('//div[@class="content-box"]/p[@class="p2"]/text()')
                # print(strr)
            for j in urls:
                resp = requests.get(j, headers=create_hdr(), proxies=proxy)
                # sss = resp.content.decode('utf8')
                parsed_url_list = re.findall(r"url \+= '(.+)'", resp.text)
                parsed_url = ''.join(parsed_url_list)
                parsed_url = re.sub(r'@', r'', parsed_url)
                print(parsed_url)


if __name__ == '__main__':
    crowler('12306')

这里我贴上用pycharm编写的爬虫程序,原理不在这里过多讲述。

但是,尽管能搜狗微信在短时间内爬取数量过多时,会触发验证机制。这就是这个项目没有很好解决的需要改进的地方。目前的方法是等一段时间再爬取,或者直接提示触发反爬。

综上
from urllib.parse import (
    quote,
    urlencode,
)
from lxml import html
import random
import requests
import re
from searx.utils import (
    eval_xpath_getindex,
    eval_xpath_list,
    extract_text,
)
from time import sleep

URL = ''
hder = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
    Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0',
    'Cookie': 'ABTEST=0|1722388018|v1; SUID=A2FECF7C1252A20B0000000066A98E32; \
    IPLOC=CN1100; SUID=A2FECF7C1AA7A20B0000000066A98E34; SUV=005224EA7CCFFEA266A99380942FF064; \
    ssuid=6905076304; PHPSESSID=laqcp42b40k82bcnplh7e47to1; SNUID=194273C0BCBDA49EE380D5D1BC347914; \
    ariaDefaultTheme=undefined',
}
# proxy = {'http': '192.168.0.123', 'https': '192.168.0.123'}

about={
    "website": 'https://weixin.sogou.com/weixin',
    "wikidata_id": None,
    "official_api_documentation": None,
    "use_official_api": False,
    "require_api_key": False,
    "results": 'HTML',
}
categories = ['general', 'web']
paging = True
time_range_support = False


def request(query, params):
    global URL
    base_url = 'http://weixin.sogou.com/weixin'
    args = urlencode(
        {
            'query':quote(query),
            'page':1,
            'type':2,
        }
    )
    global URL
    URL = base_url + '?' + args
    # params['url'] = base_url + '?' + args
    word_pools = ['nihao', 'hello', 'nihaoma', 'how are you']
    params['url'] = f'https://www.google.com.hk/search?q={random.choice(word_pools)}'
    params['headers']['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)\
     Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0'
    params['cookies'] = {'ABTEST': '0|1722388018|v1',
        'SUID': 'A2FECF7C1252A20B0000000066A98E34',
        'IPLOC': 'CN1100',
        'SUV': '005224EA7CCFFEA266A99380942FF064',
        'ssuid': '6905076304',
        'PHPSESSID': 'laqcp42b40k82bcnplh7e47to1',
        'SNUID': '194273C0BCBDA49EE380D5D1BC347914',
        'ariaDefaultTheme': 'undefined'
        }
    return params


def parse_url(url_string):
    url = 'https://weixin.sogou.com' + url_string
    b = random.randint(0, 99)
    a = url.index('url=')
    a = url[a + 30 + b:a + 31 + b:]
    url += '&k=' + str(b) + '&h=' + a
    return url


def parse_url2(url_string):
    resp = requests.get(url_string, headers=hder)#, proxies=proxy)
    if resp.status_code >= 300:
        print(resp.status_code)
    parsed_url_list = re.findall(r"url \+= '(.+)'", resp.text)
    parsed_url = ''.join(parsed_url_list)
    parsed_url = re.sub(r'@', r'', parsed_url)
    return parsed_url


def response(resp):
    results = []
    for page in range(1,6):
        global URL
        URL += f'&page={page}'
        respp = requests.get(URL,headers=hder)#,proxies=proxy)
        vrfy_str = '此验证码用于确认这些请求是您的正常行为而不是自动程序发出的,需要您协助验证'
        if vrfy_str in respp.text:
            text = f'搜狗微信触发反爬程序,请过段时间使用该引擎,或点击验证(跳转到搜狗界面),第{page}页'
            results.append({'url': respp.url, 'title': 'weixin_verify', 'content': text})
        else:
            dom = html.fromstring(respp.text)
            print(respp.text)
            for result in eval_xpath_list(dom, '//div[contains(@class,"txt-box")]'):
                url = eval_xpath_getindex(result, './/h3/a/@href', 0, default=None)
                if url is None:
                    print("???")
                    continue
                url = parse_url(url)
                print(url)
                urll = parse_url2(url)
                print(urll)
                if urll != '':
                    url = urll
                title1 = eval_xpath_getindex(result, './/h3//a/text()', 0, default='')
                title2 = eval_xpath_getindex(result, './/h3//a/text()', 1, default='')
                title3 = eval_xpath_getindex(result, './/h3//a/text()', 2, default='')
                title_em1 = eval_xpath_getindex(result, './/h3//a/em/text()', 0, default='')
                title_em2 = eval_xpath_getindex(result, './/h3//a/em/text()', 1, default='')
                if title2 == '':
                    title = extract_text(title_em1 + title1)
                else:
                    title = extract_text(title1+title_em1+title2+title_em2+title3)
                content = eval_xpath_getindex(result, './/p[contains(@class, "txt-info")]', 0, default='')
                content = extract_text(content, allow_none=True)
                # append result
                results.append({'url': url, 'title': title, 'content': content})
    return results

我在这里贴上了完整的wechat.py的文件。注:这里使用的方法是绕开searxng自己编写的request函数,而是采取了调用第三方requests库的方式(频繁触发反爬真的很头疼,所以采用这种方法增加页面的可塑性)。当然,使用自带函数也可以,但是没那么自由就是了。如果有机会我会再贴上这种方法的完整代码的。

四、结语

这个项目作为我的实习内容来说确实是有一定挑战的,很多时候就是看着电脑发懵,完全不知所措,不知道问题出在哪里,不会很多方法和技术。但是这一个月时间也是慢慢磨练自己吧,从不会到自学到会的过程真的很爽。虽然自己深知自己做出来的东西其实还是个不完美的残次品,但它的存在也能极大程度的激励我,每每遇到困难时便能回想起来当时的经历,相信自己,没什么问题是没办法解决的。




推荐本站淘宝优惠价购买喜欢的宝贝:

部署SearXNG并且把集成搜狗微信这件事

本文链接:https://hqyman.cn/post/9573.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: