python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

高洛峰
풀어 주다: 2017-02-14 13:42:12
원래의
2775명이 탐색했습니다.

이 글은 주로 python3 Baidu 인덱스 크롤링을 소개합니다. 편집자는 이것이 꽤 좋다고 생각합니다. 이제 여러분과 공유하고 참고용으로 제공하겠습니다. 편집자를 따라가서 살펴보겠습니다.

바이두 지수를 파악한 후 이미지 인식을 사용해 지수를 얻습니다

서문:

투푸는 바이두 지수가 파악하기 어렵고 비용이 20이라고 말한 적이 있습니다. 타오바오 항목당 만원 키워드:

python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

사람이 어떻게 그 사람을 두려워할 수 있어서 2일 반 정도 걸려서 완성했어요. 🎜>

설치된 라이브러리가 많습니다:

谷歌图像识别tesseract-ocr

pip3 install pillow

pip3 install pyocr

selenium2.45

Chrome47.0.2526.106 m or Firebox32.0.1

chromedriver.exe
로그인 후 복사

Baidu Index에 들어가려면 로그인이 필요합니다. 로그인 계정과 비밀번호는 텍스트 계정에 기록되어 있습니다.


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

범용 로그인 코드는 다음과 같습니다.


# 打开浏览器
def openbrowser():
  global browser

  # http://www.php.cn/
  url = "https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F"
  # 打开谷歌浏览器
  # Firefox()
  # Chrome()
  browser = webdriver.Chrome()
  # 输入网址
  browser.get(url)
  # 打开浏览器时间
  # print("等待10秒打开浏览器...")
  # time.sleep(10)

  # 找到id="TANGRAM__PSP_3__userName"的对话框
  # 清空输入框
  browser.find_element_by_id("TANGRAM__PSP_3__userName").clear()
  browser.find_element_by_id("TANGRAM__PSP_3__password").clear()

  # 输入账号密码
  # 输入账号密码
  account = []
  try:
    fileaccount = open("../baidu/account.txt")
    accounts = fileaccount.readlines()
    for acc in accounts:
      account.append(acc.strip())
    fileaccount.close()
  except Exception as err:
    print(err)
    input("请正确在account.txt里面写入账号密码")
    exit()
  browser.find_element_by_id("TANGRAM__PSP_3__userName").send_keys(account[0])
  browser.find_element_by_id("TANGRAM__PSP_3__password").send_keys(account[1])

  # 点击登陆登陆
  # id="TANGRAM__PSP_3__submit"
  browser.find_element_by_id("TANGRAM__PSP_3__submit").click()

  # 等待登陆10秒
  # print('等待登陆10秒...')
  # time.sleep(10)
  print("等待网址加载完毕...")

  select = input("请观察浏览器网站是否已经登陆(y/n):")
  while 1:
    if select == "y" or select == "Y":
      print("登陆成功!")
      print("准备打开新的窗口...")
      # time.sleep(1)
      # browser.quit()
      break

    elif select == "n" or select == "N":
      selectno = input("账号密码错误请按0,验证码出现请按1...")
      # 账号密码错误则重新输入
      if selectno == "0":

        # 找到id="TANGRAM__PSP_3__userName"的对话框
        # 清空输入框
        browser.find_element_by_id("TANGRAM__PSP_3__userName").clear()
        browser.find_element_by_id("TANGRAM__PSP_3__password").clear()

        # 输入账号密码
        account = []
        try:
          fileaccount = open("../baidu/account.txt")
          accounts = fileaccount.readlines()
          for acc in accounts:
            account.append(acc.strip())
          fileaccount.close()
        except Exception as err:
          print(err)
          input("请正确在account.txt里面写入账号密码")
          exit()

        browser.find_element_by_id("TANGRAM__PSP_3__userName").send_keys(account[0])
        browser.find_element_by_id("TANGRAM__PSP_3__password").send_keys(account[1])
        # 点击登陆sign in
        # id="TANGRAM__PSP_3__submit"
        browser.find_element_by_id("TANGRAM__PSP_3__submit").click()

      elif selectno == "1":
        # 验证码的id为id="ap_captcha_guess"的对话框
        input("请在浏览器中输入验证码并登陆...")
        select = input("请观察浏览器网站是否已经登陆(y/n):")

    else:
      print("请输入“y”或者“n”!")
      select = input("请观察浏览器网站是否已经登陆(y/n):")
로그인 후 복사

로그인 페이지:


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

로그인한 후 새 창을 열어야 합니다. 즉, Baidu Index를 열고 창을 전환해야 합니다. Selenium에서는 다음을 사용하세요.


# 新开一个窗口,通过执行js来新开一个窗口
js = 'window.open("http://index.baidu.com");'
browser.execute_script(js)
# 新窗口句柄切换,进入百度指数
# 获得当前打开所有窗口的句柄handles
# handles为一个数组
handles = browser.window_handles
# print(handles)
# 切换到当前最新打开的窗口
browser.switch_to_window(handles[-1])
로그인 후 복사

입력 상자를 지우고 클릭 일 수를 구성합니다.


# 清空输入框
browser.find_element_by_id("schword").clear()
# 写入需要搜索的百度指数
browser.find_element_by_id("schword").send_keys(keyword)
# 点击搜索
# <input type="submit" value="" id="searchWords" onclick="searchDemoWords()">
browser.find_element_by_id("searchWords").click()
time.sleep(2)
# 最大化窗口
browser.maximize_window()
# 构造天数
sel = int(input("查询7天请按0,30天请按1,90天请按2,半年请按3:"))
day = 0
if sel == 0:
  day = 7
elif sel == 1:
  day = 30
elif sel == 2:
  day = 90
elif sel == 3:
  day = 180
sel = &#39;//a[@rel="&#39; + str(day) + &#39;"]&#39;
browser.find_element_by_xpath(sel).click()
# 太快了
time.sleep(2)
로그인 후 복사

일수는 다음과 같습니다.


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

그래픽 상자 찾기:


xoyelement = browser.find_elements_by_css_selector("#trend rect")[2]
로그인 후 복사

그래픽 상자는 다음과 같습니다.


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

다양한 좌표점을 기반으로 오프셋 구성:


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

관측할 7일 좌표 선택:

아니요. 한 점의 가로좌표는 1031.66666

두 번째 점의 가로좌표는 1234


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

두 좌표 사이의 거리는 7일입니다. 차이는 202.33이고 다른 날은 비슷합니다

Selenium 라이브러리를 사용하여 마우스 슬라이딩 및 호버링 시뮬레이션:


from selenium.webdriver.common.action_chains import ActionChains
ActionChains(browser).move_to_element_with_offset(xoyelement,x_0,y_0).perform()
로그인 후 복사

그러나 이것은 확실합니다. 요점은 이 위치에서 지적됩니다:


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

팝업 상자를 표시하기 위해 직사각형의 왼쪽 상단 모서리가 여기에 로드되지 않으므로 가로좌표 + 1:


x_0 = 1
y_0 = 0
로그인 후 복사

일수를 기준으로 루프를 작성하고 가로좌표를 누적합니다.


# 按照选择的天数循环
for i in range(day):
  # 构造规则
  if day == 7:
    x_0 = x_0 + 202.33
  elif day == 30:
    x_0 = x_0 + 41.68
  elif day == 90:
    x_0 = x_0 + 13.64
  elif day == 180:
    x_0 = x_0 + 6.78
로그인 후 복사

마우스를 가로로 움직이면 상자가 나타납니다. URL의 이 상자:


python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

Selenium은 자동으로 인식합니다...:


# <p class="imgtxt" style="margin-left:-117px;"></p>
imgelement = browser.find_element_by_xpath(&#39;//p[@id="viewbox"]&#39;)
로그인 후 복사

이 상자의 크기와 위치를 결정합니다.


# 找到图片坐标
locations = imgelement.location
print(locations)
# 找到图片大小
sizes = imgelement.size
print(sizes)
# 构造指数的位置
rangle = (int(locations[&#39;x&#39;]), int(locations[&#39;y&#39;]), int(locations[&#39;x&#39;] + sizes[&#39;width&#39;]),
     int(locations[&#39;y&#39;] + sizes[&#39;height&#39;]))
로그인 후 복사

캡처된 그래픽은 다음과 같습니다.

python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

다음 아이디어는 다음과 같습니다.

1. 전체 화면의 스크린샷을 찍습니다


2. 스크린샷을 열고 위에서 얻은 좌표 범위를 사용합니다. 자르기

하지만 최종 자르기는 위의 검은색 프레임입니다. 제가 원하는 효과는 다음과 같습니다.

python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

그래서 범위를 계산해야 하는데 게으릅니다. 검색어의 길이를 무시하고 직설적으로 폭력적으로 씁니다:


# 构造指数的位置
rangle = (int(locations[&#39;x&#39;] + sizes[&#39;width&#39;]/3), int(locations[&#39;y&#39;] + sizes[&#39;height&#39;]/2), int(locations[&#39;x&#39;] + sizes[&#39;width&#39;]*2/3),
     int(locations[&#39;y&#39;] + sizes[&#39;height&#39;]))
로그인 후 복사

这个写法最终不太好,最起码要对keyword的长度进行判断,长度过长会导致截图坐标出现偏差,反正我知道怎么做,就是不写出来给你们看!

后面的完整代码是:

# <p class="imgtxt" style="margin-left:-117px;"></p>
imgelement = browser.find_element_by_xpath(&#39;//p[@id="viewbox"]&#39;)
# 找到图片坐标
locations = imgelement.location
print(locations)
# 找到图片大小
sizes = imgelement.size
print(sizes)
# 构造指数的位置
rangle = (int(locations[&#39;x&#39;] + sizes[&#39;width&#39;]/3), int(locations[&#39;y&#39;] + sizes[&#39;height&#39;]/2), int(locations[&#39;x&#39;] + sizes[&#39;width&#39;]*2/3),
     int(locations[&#39;y&#39;] + sizes[&#39;height&#39;]))
# 截取当前浏览器
path = "../baidu/" + str(num)
browser.save_screenshot(str(path) + ".png")
# 打开截图切割
img = Image.open(str(path) + ".png")
jpg = img.crop(rangle)
jpg.save(str(path) + ".jpg")
로그인 후 복사

但是后面发现裁剪的图片太小,识别精度太低,所以需要对图片进行扩大:

# 将图片放大一倍
# 原图大小73.29
jpgzoom = Image.open(str(path) + ".jpg")
(x, y) = jpgzoom.size
x_s = 146
y_s = 58
out = jpgzoom.resize((x_s, y_s), Image.ANTIALIAS)
out.save(path + &#39;zoom.jpg&#39;, &#39;png&#39;, quality=95)
로그인 후 복사

原图大小请 右键->属性->详细信息 查看,我的是长73像素,宽29像素

最后就是图像识别

# 图像识别
index = []
image = Image.open(str(path) + "zoom.jpg")
code = pytesseract.image_to_string(image)
if code:
  index.append(code)
로그인 후 복사

最后效果图:

python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명

python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。

更多python3 Baidu 인덱스 크롤링 예제에 대한 자세한 설명相关文章请关注PHP中文网!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿