junda 发表于 2022-2-6 12:03

【抓需求必备】百度相关搜索循环爬虫

前阵子看了篇文章,做百度相关搜索的循环爬取用于抓需求。

方法是爬取百度相关搜索结果,然后通过判断同页面的百度搜索结果的域名和我的域名库的交集是否大于2,从而判断这个相关搜索是不是我所需要的。
然后循环爬取,可以积累大量同领域相关的问题。

没学过编程,自学了一周,把这个代码手撸了出来,水平有限,代码逻辑写的乱,欢迎各位大佬修改拍砖。


import threading
from concurrent.futures import ThreadPoolExecutor
import requests
from lxml import etree
import queue
import urllib
from urllib import parse
import urllib.request
from urllib.parse import urlparse
import json


lock = threading.Lock()
proxies = {

}

# cookie自己抓
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36',
    'Cookie': ''
}
# 1:循环提取队列关键词到百度搜索,提取结果页面的链接和标题。
def get_domain(url):#获得主域名
    domain =urlparse(url).hostname
    return domain

def get_url(baidu_url):#转换为原始url
    header = requests.head(baidu_url).headers
    url = header.get('location')
    return url

def get_new_key(tree): #返回新的关键词列表
    new_key = tree.xpath('//*[@id="rs_new"]/table/tbody/tr/td/a/@title')
    return new_key

def get_web_data(tree): #获得页面数据列表
    all_webdata = tree.xpath('//h3/a')
    web_data = []
    for it in all_webdata:
      x = it.xpath('string(.)')
      web_data.append(x)
    return web_data
# 2:将提取出的百度链接批量转化为原始URL,提取所有原始URL的主域名与行业域名库比对(转化为set集合取交集)。
def get_result(key): #获得最终关键词
    search_link = 'https://www.baidu.com/s?ie=utf-8&wd=%s&pn=20' % urllib.parse.quote(key)
    resp = requests.get(search_link,headers = headers,proxies=proxies)
    html= resp.text
    tree = etree.HTML(html)
    baidu_url = tree.xpath('//*[@id="content_left"]/div')
    with lock:
      ls = set() #不要的字典
      for it in baidu_url:
            try:
                bd_url = it.xpath('h3/a/@href')
            except IndexError:
                continue
            url = get_url(bd_url)
            domain = get_domain(url)
            ls.add(domain)
      # 根据设置的阈值(一般设置25%左右,10个链接2-3个命中即可,没有固定标准)判断是否为目标领域词,根据得到的判定选择是否提取和保存”相关搜索”词。
      if len(ls&need_url)>2:
            new_key = get_new_key(tree)
            web_data = get_web_data(tree)
            print(f"抓取关键词【{key}】:完成")
            return new_key,web_data
      else:
            outcast_key.add(key)
            print(f"抓取关键词【{key}】:异类")


if __name__ == '__main__':
    main_key = ['育儿']
    seen_key = set(main_key)
    # 所需数据
    key_web_data = dict()
    outcast_key = set()
    # 所需url的字典
    f = open('needurl.txt', 'r+',encoding='UTF-8')
    need_url = {'www.baidu.com'}
    txt = f.readlines()
    for it in txt:
      need_url.add(it.strip())
    print('任务开始!请不要随意关闭!')
    # 设置队列
    queue_key = queue.Queue()
    pool = ThreadPoolExecutor(50)# 多线程
    # 关键词放入队列中
    for key in seen_key: # 当关键词在seen_key里
      queue_key.put(key) #把seen_key的关键词加入到队列中
      while queue_key.empty() == False:
            key = queue_key.get()#从队列获取关键词
            if key in key_web_data: continue #当关键词在已储存数据里,跳过
            if key in outcast_key:continue #当关键词在不要的关键词里,跳过
            try:
                # new_key,web_data = get_result(key) #单线程
                new_key, web_data = pool.submit(get_result,key).result()   
                for nk in new_key:
                  if nk in seen_key: continue
                  seen_key.add(nk)
                  queue_key.put(nk)
                  key_web_data = web_data

                  if len(key_web_data) >= 2000:
                        print('爬取完成')
                        break
                # 保存成json
                json_str = json.dumps(key_web_data, indent=4)
                with open(f'{main_key}data.json', 'a+') as json_file:
                  json_file.write(json_str)
                  json_file.flush()
                # 保存成txt
                with open(f'{main_key}关键词.txt', 'a+', encoding='UTF-8') as datatxt:
                  datatxt.write(key + '\n')
                  datatxt.flush()
            except TypeError:
                continue

开创者 发表于 2022-2-10 10:44

junda 发表于 2022-2-10 10:42
需要登录一个百度账号

登录着的呢,一直登录着的。感觉还是弄的不对,我看那种友情链接平台都可以实现,估计还是代码搞的不对,自己不会写,从网上复制的,添加了cookie。后来又找到了说设置账号密码的(有些复杂了,需要装很多东西),还是没研究会。

开创者 发表于 2022-2-10 10:20

junda 发表于 2022-2-10 09:57
打开百度-随便搜索什么-右键检查-点击network-点击fetch/xhr-刷新页面-会看到里面有很多文件-随便点一个- ...

之前这样弄过(网上找的一段抓取代码,添加了这个cookie),但不知道那弄的不对。结果搜索的时间还是提示百度安全验证

1225661221 发表于 2022-2-6 18:35

实话实说,现成的我还能吃一下,这个实在是吃不下。。。。。。。。。。。。

fangben518 发表于 2022-2-6 19:20

我怕吃撑了

sun12345 发表于 2022-2-6 20:44

看的迷糊

wu_yang007 发表于 2022-2-6 21:46

一个星期就这么厉害了,好多好多看不懂

junda 发表于 2022-2-7 11:30

1225661221 发表于 2022-2-6 18:35
实话实说,现成的我还能吃一下,这个实在是吃不下。。。。。。。。。。。。

汗,是我写的不好,见谅

开创者 发表于 2022-2-8 09:36

不需要验证吗?现在百度一搜索就要验证啊

junda 发表于 2022-2-8 12:35

开创者 发表于 2022-2-8 09:36
不需要验证吗?现在百度一搜索就要验证啊

带上cookie 登录的百度账号

开创者 发表于 2022-2-8 14:13

junda 发表于 2022-2-8 12:35
带上cookie 登录的百度账号

我知道,就是具体不知道怎么弄,能给个示例不 ?

junda 发表于 2022-2-10 09:57

开创者 发表于 2022-2-8 14:13
我知道,就是具体不知道怎么弄,能给个示例不 ?

打开百度-随便搜索什么-右键检查-点击network-点击fetch/xhr-刷新页面-会看到里面有很多文件-随便点一个-就能看到里面有cookie了
页: [1] 2
查看完整版本: 【抓需求必备】百度相关搜索循环爬虫